UOJ#414. 【APIO2018】新家
传送门
首先二分答案 \(mid\),问题变成求区间 \([l-mid,r+mid]\) 在该年份的不同类型个数为 \(k\)
关于年份的限制可以离线下来
现在的问题就是区间数颜色,一个套路就是维护每个颜色的后继,即这个位置颜色的下一个位置
那么,如果有 \((-\infty,l-mid-1]\) 的某一个值大于 \(r+mid\) 就不合法
这个可以在线段树上二分实现
时间复杂度 \(nlogn\)
# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
namespace IO {
const int maxn(1 << 21 | 1);
char obuf[maxn], ibuf[maxn], *iS, *iT, c, *oS = obuf, *oT = obuf + maxn - 1, st[60];
int f, tp;
inline char Getc() {
return iS == iT ? (iT = (iS = ibuf) + fread(ibuf, 1, maxn, stdin), (iS == iT ? EOF : *iS++)) : *iS++;
}
template <class Int> inline void In(Int &x) {
for (c = Getc(), f = 1; c < '0' || c > '9'; c = Getc()) f = c == '-' ? -1 : 1;
for (x = 0; c >= '0' && c <= '9'; c = Getc()) x = (x << 1) + (x << 3) + (c ^ 48);
x *= f;
}
inline void Flush() {
fwrite(obuf, 1, oS - obuf, stdout);
oS = obuf;
}
inline void Putc(char c) {
*oS++ = c;
if (oS == oT) Flush();
}
template <class Int> inline void Out(Int x) {
if (x < 0) Putc('-'), x = -x;
if (!x) Putc('0');
while (x) st[++tp] = x % 10 + '0', x /= 10;
while (tp) Putc(st[tp--]);
}
}
using IO :: In;
using IO :: Out;
using IO :: Putc;
using IO :: Flush;
const int maxn(3e5 + 5);
const int inf(1e9);
int n, q, k, rt, tot, type, vis[maxn], ans[maxn];
multiset <int> pos[maxn], heap[maxn * 20];
multiset <int> :: iterator it, ot, at;
struct Segment {
int ls, rs, mx, vmx;
} tr[maxn * 20];
struct Store {
int tp, x, tim, op;
inline bool operator <(Store b) const {
return tim < b.tim;
}
} str[maxn << 1];
struct Qry {
int x, tim, id;
inline bool operator <(Qry b) const {
return tim < b.tim;
}
} qry[maxn];
void Modify(int &x, int l, int r, int p, int v, int op) {
int mid;
if (!x) x = ++tot;
if (l == r) {
if (op == 1) heap[x].insert(v);
else heap[x].erase(heap[x].find(v));
at = heap[x].end();
tr[x].mx = heap[x].size() ? (*--at) : -inf;
tr[x].vmx = tr[x].mx + l;
return;
}
mid = (l + r) % 2 == 0 ? (l + r) / 2 : (l + r - 1) / 2;
p <= mid ? Modify(tr[x].ls, l, mid, p, v, op) : Modify(tr[x].rs, mid + 1, r, p, v, op);
tr[x].mx = max(tr[tr[x].ls].mx, tr[tr[x].rs].mx);
tr[x].vmx = max(tr[tr[x].ls].vmx, tr[x].mx + r);
}
int Query(int x, int l, int r, int ql, int qr) {
int mid, ret;
if (ql > qr) return inf;
if (!x || (ql <= l && qr >= r)) return tr[x].mx;
ret = -inf, mid = (l + r) >> 1;
if (ql <= mid) ret = Query(tr[x].ls, l, mid, ql, qr);
if (qr > mid) ret = max(ret, Query(tr[x].rs, mid + 1, r, ql, qr));
return ret;
}
int main() {
freopen("a.in", "r", stdin);
int cnt, i, j, x, t, a, b, mx, l, r, mid, cur, nmx, tmp, vmx;
In(n), In(k), In(q), cnt = mx = 0;
for (i = 1; i <= n; ++i) {
In(x), In(t), In(a), In(b);
str[++cnt] = (Store){t, x, a, 1};
str[++cnt] = (Store){t, x, b + 1, -1};
mx = max(mx, x);
}
sort(str + 1, str + cnt + 1);
for (i = 1; i <= q; ++i) {
In(qry[i].x), In(qry[i].tim);
qry[i].id = i, mx = max(mx, qry[i].x);
}
sort(qry + 1, qry + q + 1), tr[0].vmx = tr[0].mx = -inf;
for (i = 1; i <= k; ++i) pos[i].insert(-mx), pos[i].insert(inf), Modify(rt, -mx, mx, -mx, inf, 1);
for (i = 1, j = 1; i <= q; ++i) {
while (j <= cnt && str[j].tim <= qry[i].tim) {
if (str[j].op == 1) {
type += (vis[str[j].tp] == 0), ++vis[str[j].tp];
ot = it = pos[str[j].tp].insert(str[j].x);
--it, ++ot;
Modify(rt, -mx, mx, *it, *ot, -1);
Modify(rt, -mx, mx, *it, str[j].x, 1);
Modify(rt, -mx, mx, str[j].x, *ot, 1);
}
else {
type -= (vis[str[j].tp] == 1), --vis[str[j].tp];
ot = it = pos[str[j].tp].find(str[j].x);
--it, ++ot;
Modify(rt, -mx, mx, *it, *ot, 1);
Modify(rt, -mx, mx, *it, str[j].x, -1);
Modify(rt, -mx, mx, str[j].x, *ot, -1), ++it, pos[str[j].tp].erase(it);
}
++j;
}
if (type != k) ans[qry[i].id] = -1;
else {
l = -mx, r = mx, cur = rt, vmx = nmx = -inf;
while (l < r) {
mid = (l + r) >> 1;
tmp = max(nmx + mid, tr[tr[cur].ls].vmx);
if (tmp >= qry[i].x + qry[i].x || qry[i].x <= mid + 1) cur = tr[cur].ls, r = mid;
else vmx = tmp, nmx = max(nmx, tr[tr[cur].ls].mx), cur = tr[cur].rs, l = mid + 1;
}
if (Query(rt, -mx, mx, -mx, l) + l >= qry[i].x + qry[i].x) --l;
ans[qry[i].id] = qry[i].x - l - 1;
}
}
for (i = 1; i <= q; ++i) Out(ans[i]), Putc('\n');
return Flush(), 0;
}
UOJ#414. 【APIO2018】新家的更多相关文章
- 「APIO2018新家」
「APIO2018新家」 题目描述 五福街是一条笔直的道路,这条道路可以看成一个数轴,街上每个建筑物的坐标都可以用一个整数来表示.小明是一位时光旅行者,他知道在这条街上,在过去现在和未来共有 \(n\ ...
- LOJ.2585.[APIO2018]新家(二分 线段树 堆)
LOJ 洛谷 UOJ BZOJ 四OJ Rank1 hhhha 表示这个b我能装一年→_→ 首先考虑离线,将询问按时间排序.对于每个在\([l,r]\)出现的颜色,拆成在\(l\)加入和\(r+1\) ...
- [loj2585][APIO2018]新家
题目 一条街上有\(n\) 个点,坐标为\(x_i\) , 店的种类为\(t_i\) , 开业时间为 \([a_i,b_i]\) ; 定义一种类型到一个点的距离为这种类的点到这个点的最近距离 ; 定义 ...
- BZOJ5462 APIO2018新家(线段树+堆)
一个显然的做法是二分答案后转化为查询区间颜色数,可持久化线段树记录每个位置上一个同色位置,离线后set+树状数组套线段树维护.这样是三个log的. 注意到我们要知道的其实只是是否所有颜色都在该区间出现 ...
- [BZOJ5462][APIO2018]新家(线段树+堆)
其实这个题第一反应一定是线段树分治,但是这样反而更难考虑了(实际上是可做的但很难想到),可见即使看上去最贴切的算法也未必能有效果. 考虑这个DS题,没有什么模型的转化,可能用到的无非就是线段树.平衡树 ...
- 【APIO2018】新家(线段树)
[APIO2018]新家(线段树) 题面 UOJ 洛谷 BZOJ 题解 论比赛时想不到二分的危害,就只能Cu滚粗 既然不要在线,那么考虑离线做法. 既然时间是区间,那么显然按照时间顺序处理答案. 显然 ...
- LOJ #2585. 「APIO2018」新家
#2585. 「APIO2018」新家 https://loj.ac/problem/2585 分析: 线段树+二分. 首先看怎样数颜色,正常的时候,离线扫一遍右端点,每次只记录最右边的点,然后查询左 ...
- 此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist
此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist
- BZOJ 3631 【JLOI2014】 松鼠的新家
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树&q ...
- 【BZOJ-3631】松鼠的新家 树形DP?+ 倍增LCA + 打标记
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1231 Solved: 620[Submit][Stat ...
随机推荐
- URL的组成和含义
1.URL - Uniform Resource Locator 当您点击 HTML 页面中的某个链接时,对应的 <a>标签指向万维网上的一个地址. 统一资源定位器(URL)用于定位万维网 ...
- 总结day13 ----内置函数
内置函数 我们一起来看看python里的内置函数.什么是内置函数?就是Python给你提供的,拿来直接用的函数,比如print,input等等.截止到python版本3.6.2,现在python一共为 ...
- 【Quartz】基本原理
1 核心概念 1.1 核心元素 (1)Scheduler 任务调度器,是Quartz框架的核心,负责管理其他组件. (2)Trigger 触发器,用于定义任务调度的时间规则,有SimpleTri ...
- jenkins运行Python
法一: 配置中构建执行Windows批处理命令如下 立即构建后,报错如下,提示python 不是内部或外部指令 修改Windows批处理指令如下: 再次“立即构建”则正常 法二: 安装Python插件 ...
- panda的query过滤
pandas中可以用query函数以类SQL语言执行查询.
- 题解 [ZJOI2010]数字计数
传送门<-洛谷版 电梯<-bzoj版 这份代码是新手友好版,也算是自用版,注释自认为写的很详细. 希望对要学数位dp的人有所帮助 这份题解是记忆化搜索版的数位DP,个人还是比较建议用这种方 ...
- 2018徐州网络赛 - Trace
题意:n个左下角为原点右上角在第一象限的矩形不断覆盖,求最后形成的图形的周长 x和y是独立的,分别维护两棵线段树,一棵表示x坐标下最大的y值,另一棵表示y坐标下最大的x值 从覆盖的角度来考虑,如果逆序 ...
- js img转换base64
方法一:canvas <script type="text/javascript"> function getBase64Image(img) { var canvas ...
- [转] linux alias 编写 函数 脚本
[From] https://blog.csdn.net/csdnmonkey/article/details/53286314 案例 alias ttt='ttt(){ echo $1 ; };tt ...
- centos 7修改系统支持中文编码
2019-03-14 查看系统现支持编码 }[root@web dc2-user]#locale LANG=en_US.UTF- LC_CTYPE="en_US.UTF-8" LC ...