#2585. 「APIO2018」新家

https://loj.ac/problem/2585

分析:

  线段树+二分。

  首先看怎样数颜色,正常的时候,离线扫一遍右端点,每次只记录最右边的点,然后查询左端点,这里不太行。这里只需要统计是否全出现过,pre[i]为这个颜色的上一个位置,那么这也就说明了pre[i]+1这段区间没出现过,所以要求[r+1,n]这段区间的最小的pre都要大于等于l。于是这就是线段树区间查询最小值了。

  注意的是,每个点的pre有多个,每个叶子节点包含一个set,把所有的值插入进去,取最小值。用两个堆维护也可以,(取最小值,删除一个值)。

  然后就可以二分一个长度,然后查询[x-len,x+len]这段区间是否都有所有的颜色就行了。复杂度$O(nlog^2n)$

  一个log的做法,二分的过程放到了线段树上。  

代码:

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
const int INF = 1e9; struct Node{
int opt, x, col, t;
Node() {}
Node(int a,int b,int c,int d) { opt = a, x = b, col = c, t = d; }
bool operator < (const Node &A) const {
return t == A.t ? opt > A.opt : t < A.t; // 如果时间相同,先加入,在询问,再删除
}
}A[N * ];
struct Heap{
priority_queue<int, vector<int>, greater<int> > q1, q2;
int size() { return q1.size() - q2.size(); }
void add(int x) { q1.push(x); }
void del(int x) { q2.push(x); }
int top() {
while (!q2.empty() && q1.top() == q2.top()) q1.pop(), q2.pop();
return q1.top();
}
// multiset<int> s;
// int size() { return s.size(); }
// void add(int x) { s.insert(x); }
// void del(int x) { s.erase(s.find(x)); }
// int top() { return *s.begin(); }
}H[N];
multiset<int> S[N];
int ans[N], Id[N * ], ls[N * ], rs[N * ], Mn[N * ];
int n, k, m, Index_Heap, Index_Tree, Root, Now_Col; void update(int l,int r,int &rt,int p,int u,int v) {
if (!rt) rt = ++Index_Tree;
if (l == r) {
if (!Id[rt]) Id[rt] = ++Index_Heap;
Heap &now = H[Id[rt]];
if (u) now.add(u);
if (v) now.del(v);
Mn[rt] = now.size() ? now.top() : INF;
return ;
}
int mid = (l + r) >> ;
if (p <= mid) update(l, mid, ls[rt], p, u, v);
else update(mid + , r, rs[rt], p, u, v);
Mn[rt] = min(Mn[ls[rt]], Mn[rs[rt]]);
}
void add(const Node &now) {
multiset<int> &s = S[now.col];
multiset<int> :: iterator r = s.upper_bound(now.x), l = r; l--;
update(, INF, Root, *r, now.x, *l);
update(, INF, Root, now.x, *l, );
if (s.size() == ) Now_Col ++;
s.insert(now.x);
}
void del(const Node &now) {
multiset<int> &s = S[now.col];
s.erase(s.find(now.x));
if (s.size() == ) Now_Col --;
multiset<int> :: iterator r = s.upper_bound(now.x), l = r; l--;
update(, INF, Root, *r, *l, now.x);
update(, INF, Root, now.x, , *l);
}
int Ask(int p) {
if (Now_Col != k) return -;
int l = , r = INF, now = Root, ans = INF;
while (l != r) { // 模拟在线段树上走的过程
int mid = (l + r) >> , tmp = min(ans, Mn[rs[now]]);
if (p <= mid && tmp + mid >= p + p) ans = tmp, r = mid, now = ls[now];
else l = mid + , now = rs[now];
}
return l - p;
}
int main() {
n = read(), k = read(), m = read();
Mn[] = INF;
for (int i = ; i <= k; ++i) // 初始往INF处加入k个-INF
S[i].insert(-INF), S[i].insert(INF), update(, INF, Root, INF, -INF, );
int tot = ;
for (int i = ; i <= n; ++i) {
int x = read(), t = read(), a = read(), b = read();
A[++tot] = Node(, x, t, a); A[++tot] = Node(-, x, t, b);
}
for (int i = ; i <= m; ++i) {
int x = read(), t = read();
A[++tot] = Node(, x, i, t);
}
sort(A + , A + tot + );
for (int i = ; i <= tot; ++i) {
if (A[i].opt == ) add(A[i]);
else if (A[i].opt == -) del(A[i]);
else ans[A[i].col] = Ask(A[i].x);
}
for (int i = ; i <= m; ++i) printf("%d\n",ans[i]);
return ;
}

LOJ #2585. 「APIO2018」新家的更多相关文章

  1. LOJ 2585 「APIO2018」新家 ——线段树分治+二分答案

    题目:https://loj.ac/problem/2585 算答案的时候要二分! 这样的话,就是对于询问位置 x ,二分出一个最小的 mid 使得 [ x-mid , x+mid ] 里包含所有种类 ...

  2. 【LOJ】#2585. 「APIO2018」新家

    题解 成功把自己写自闭了 离散化之后再二分我是真不会算坐标啊我这个zz 先离散化所有坐标,然后对于每个位置维护一个最小前驱,然后线段树区间维护最小前驱 什么?位置一样?那就给每个大小为1的位置开个mu ...

  3. LOJ #2587「APIO2018」铁人两项

    是不是$ vector$存图非常慢啊...... 题意:求数对$(x,y,z)$的数量使得存在一条$x$到$z$的路径上经过$y$,要求$x,y,z$两两不同  LOJ #2587 $ Solutio ...

  4. LOJ 2586 「APIO2018」选圆圈——KD树

    题目:https://loj.ac/problem/2586 只会 19 分的暴力. y 都相等,仍然按直径从大到小做.如果当前圆没有被删除,那么用线段树把 [ x-r , x+r ] 都打上它的标记 ...

  5. LOJ 2587 「APIO2018」铁人两项——圆方树

    题目:https://loj.ac/problem/2587 先写了 47 分暴力. 对于 n<=50 的部分, n3 枚举三个点,把图的圆方树建出来,合法条件是 c 是 s -> f 路 ...

  6. 【刷题】LOJ 2587 「APIO2018」铁人两项

    题目描述 比特镇的路网由 \(m\) 条双向道路连接的 \(n\) 个交叉路口组成. 最近,比特镇获得了一场铁人两项锦标赛的主办权.这场比赛共有两段赛程:选手先完成一段长跑赛程,然后骑自行车完成第二段 ...

  7. Loj #3056. 「HNOI2019」多边形

    Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...

  8. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

  9. Loj #2719. 「NOI2018」冒泡排序

    Loj #2719. 「NOI2018」冒泡排序 题目描述 最近,小 S 对冒泡排序产生了浓厚的兴趣.为了问题简单,小 S 只研究对 *\(1\) 到 \(n\) 的排列*的冒泡排序. 下面是对冒泡排 ...

随机推荐

  1. BZOJ 1295 最长距离 BFS+枚举

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1295 题目大意: windy有一块矩形土地,被分为 N*M 块 1*1 的小格子. 有 ...

  2. BZOJ 1002 轮状病毒 矩阵树定理

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1002 题目大意: 给定n(N<=100),编程计算有多少个不同的n轮状病毒 思路 ...

  3. ApplicationEventPublisher笔记

    ApplicationEventPublisher是ApplicationContext的父接口之一.这接口的作用是:Interface that encapsulates event publica ...

  4. Debian下Cannot set LC_CTYPE to default locale: No such file or directory解决方法

    把语言环境变量改为英文 将Ubuntu系统语言环境改为英文的en_US.UTF-8 查看当前系统语言环境 locale 编辑配置文件,将zh_US.UTF-8改为en_US.UTF-8,zh改为en ...

  5. Kali-linux其他信息收集手段

    上面介绍了使用不同的工具以操作步骤的形式进行了信息收集.在Kali中还可以使用一些常规的或非常规方法来收集信息,如使用Recon-NG框架.Netdiscover工具和Shodan工具等.本节将介绍使 ...

  6. 聚类之高斯混合模型(Gaussian Mixture Model)【转】

    k-means应该是原来级别的聚类方法了,这整理下一个使用后验概率准确评测其精度的方法—高斯混合模型. 我们谈到了用 k-means 进行聚类的方法,这次我们来说一下另一个很流行的算法:Gaussia ...

  7. PHP面试系列 之Linux(六)---- 面试题整理

    1.shell命令 top:查看有哪些系统进程正在运行.该命令提供了实时对系统处理器状态的监控,它能够实时显示系统中各个进程的资源占用情况.该命令可以按照对CPU.内存使用和执行时间对系统任务进程进行 ...

  8. 阅读 CloudDPI:Cloud+DPI+Reversible Sketch

    CloudDPI: Cloud-Based Privacy-Preserving Deep Packet Inspection via Reversible Sketch 与sketch的结合点:将修 ...

  9. 映射篇:request-String-Object-Map之间相互转化(程序员的成长之路---第5篇)

    为什么写这一篇 问题一:jdbc连接数据库返回的对象是ResultSet,如何把ResultSet对象中的值转换为我们自建的各种实体类? 我估计,80%的程序员会写jdbc数据库连接,但开发项目依然用 ...

  10. Oracle11g 行列转换函数PIVOT and UNPIVOT

    作为Oracle开发工程师,推荐大伙看看 PIVOT and UNPIVOT Operators in Oracle Database 11g Release 1 This article shows ...