传送门

首先二分答案 \(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】新家的更多相关文章

  1. 「APIO2018新家」

    「APIO2018新家」 题目描述 五福街是一条笔直的道路,这条道路可以看成一个数轴,街上每个建筑物的坐标都可以用一个整数来表示.小明是一位时光旅行者,他知道在这条街上,在过去现在和未来共有 \(n\ ...

  2. LOJ.2585.[APIO2018]新家(二分 线段树 堆)

    LOJ 洛谷 UOJ BZOJ 四OJ Rank1 hhhha 表示这个b我能装一年→_→ 首先考虑离线,将询问按时间排序.对于每个在\([l,r]\)出现的颜色,拆成在\(l\)加入和\(r+1\) ...

  3. [loj2585][APIO2018]新家

    题目 一条街上有\(n\) 个点,坐标为\(x_i\) , 店的种类为\(t_i\) , 开业时间为 \([a_i,b_i]\) ; 定义一种类型到一个点的距离为这种类的点到这个点的最近距离 ; 定义 ...

  4. BZOJ5462 APIO2018新家(线段树+堆)

    一个显然的做法是二分答案后转化为查询区间颜色数,可持久化线段树记录每个位置上一个同色位置,离线后set+树状数组套线段树维护.这样是三个log的. 注意到我们要知道的其实只是是否所有颜色都在该区间出现 ...

  5. [BZOJ5462][APIO2018]新家(线段树+堆)

    其实这个题第一反应一定是线段树分治,但是这样反而更难考虑了(实际上是可做的但很难想到),可见即使看上去最贴切的算法也未必能有效果. 考虑这个DS题,没有什么模型的转化,可能用到的无非就是线段树.平衡树 ...

  6. 【APIO2018】新家(线段树)

    [APIO2018]新家(线段树) 题面 UOJ 洛谷 BZOJ 题解 论比赛时想不到二分的危害,就只能Cu滚粗 既然不要在线,那么考虑离线做法. 既然时间是区间,那么显然按照时间顺序处理答案. 显然 ...

  7. LOJ #2585. 「APIO2018」新家

    #2585. 「APIO2018」新家 https://loj.ac/problem/2585 分析: 线段树+二分. 首先看怎样数颜色,正常的时候,离线扫一遍右端点,每次只记录最右边的点,然后查询左 ...

  8. 此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist

    此博客主人已搬家访问新家地址:http://write.blog.csdn.net/postlist

  9. BZOJ 3631 【JLOI2014】 松鼠的新家

    Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树&q ...

  10. 【BZOJ-3631】松鼠的新家 树形DP?+ 倍增LCA + 打标记

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1231  Solved: 620[Submit][Stat ...

随机推荐

  1. URL的组成和含义

    1.URL - Uniform Resource Locator 当您点击 HTML 页面中的某个链接时,对应的 <a>标签指向万维网上的一个地址. 统一资源定位器(URL)用于定位万维网 ...

  2. 总结day13 ----内置函数

    内置函数 我们一起来看看python里的内置函数.什么是内置函数?就是Python给你提供的,拿来直接用的函数,比如print,input等等.截止到python版本3.6.2,现在python一共为 ...

  3. 【Quartz】基本原理

    1 核心概念 1.1    核心元素 (1)Scheduler 任务调度器,是Quartz框架的核心,负责管理其他组件. (2)Trigger 触发器,用于定义任务调度的时间规则,有SimpleTri ...

  4. jenkins运行Python

    法一: 配置中构建执行Windows批处理命令如下 立即构建后,报错如下,提示python 不是内部或外部指令 修改Windows批处理指令如下: 再次“立即构建”则正常 法二: 安装Python插件 ...

  5. panda的query过滤

    pandas中可以用query函数以类SQL语言执行查询.

  6. 题解 [ZJOI2010]数字计数

    传送门<-洛谷版 电梯<-bzoj版 这份代码是新手友好版,也算是自用版,注释自认为写的很详细. 希望对要学数位dp的人有所帮助 这份题解是记忆化搜索版的数位DP,个人还是比较建议用这种方 ...

  7. 2018徐州网络赛 - Trace

    题意:n个左下角为原点右上角在第一象限的矩形不断覆盖,求最后形成的图形的周长 x和y是独立的,分别维护两棵线段树,一棵表示x坐标下最大的y值,另一棵表示y坐标下最大的x值 从覆盖的角度来考虑,如果逆序 ...

  8. js img转换base64

    方法一:canvas <script type="text/javascript"> function getBase64Image(img) { var canvas ...

  9. [转] linux alias 编写 函数 脚本

    [From] https://blog.csdn.net/csdnmonkey/article/details/53286314 案例 alias ttt='ttt(){ echo $1 ; };tt ...

  10. centos 7修改系统支持中文编码

    2019-03-14 查看系统现支持编码 }[root@web dc2-user]#locale LANG=en_US.UTF- LC_CTYPE="en_US.UTF-8" LC ...