传送门

首先二分答案 \(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. python random 之基础点名器

    import os ,sysimport randomcalled =set() # 创建一个空集合f =open('name.txt ' , 'r')#打开文件读取名字data =f.read()# ...

  2. 核心API的使用(给定一个字符串,统计每个字符出现的次数)

    /** * 给定一个字符串,统计每个字符出现的次数. 如:abdaewrwqask435a1aasd */public class ReplaceString { static int length; ...

  3. 4、TensorFlow基础(二)常用API与变量作用域

    1.图.操作和张量 TensorFlow 的计算表现为数据流图,所以 tf.Graph 类中包含一系列表示计算的操作对象(tf.Operation),以及在操作之间流动的数据 — 张量对象(tf.Te ...

  4. shell-008:检测502

    检测502的方法有多种 1.curl他的状态码(不建议,会对网站造成不必要的访问和多余的日志输出) 2.可以直接检测访问日志 下面用while做成一个死循环监控日志502的状态 #!/bin/bash ...

  5. [BZOJ 2894]世界线

    传送门 \(\color{green}{solution}\) 在开这道题之前建议先看看3756:pty的字符串,然后你会发现这题就很zz了. 当然,作为一名合格的博主,我还是应该写点什么的 首先,我 ...

  6. 洛谷P3830 [SHOI2012]随机树(期望dp)

    题面 luogu 题解 第一问: 设\(f[i]\)表示\(i\)步操作后,平均深度期望 \(f[i] = \frac {f[i - 1] * (i - 1)+f[i-1]+2}{i}=f[i-1]+ ...

  7. HDU - 4630 离线处理区间点对问题

    题意:给定\(a[1...n]\),多次询问\([L,R]\)中的任意一对数使得\(gcd(a_i,a_j)\)最大 对于gcd,区间内至少存在两个相同的因子才能作为合法的解,存在两个相同因子且最大就 ...

  8. centos安装图形操作界面

    yum groupinstall "GNOME Desktop" "Graphical Administration Tools"

  9. easyui的datagrid对应的java对象

    Easyui中datagrid控件要求的数据格式为: {total:”2”,rows:[{“id”:”1”,”name”,”张三”},{“id”:”2”,”name”,”李四”}]} 所以可以建一个对 ...

  10. Path;Paths和Files;FileVisitor

    package filet; import java.io.FileOutputStream; import java.nio.file.FileStore; import java.nio.file ...