【做题】CERC2017B. Buffalo Barricades——时间倒流
原文链接 https://www.cnblogs.com/cly-none/p/CERC2017B.html
题意:在一个网格平面上,有\(n\)个点,其中第\(i\)个点在以\((x_i, y_i)\)为右上角的网格中。有\(m\)次操作,每次给出一个点\((x,y)\),表示从\((x,y)\)开始,向左和向下画线直到与之前画的线或坐标轴相交。这样会划分出以\((x,y)\)为右上角的新区域。你需要对每次操作求出,新区域中点的数量。
$n , m \leq 3 \times 10^5, \ 1 \leq x_i, y_i \leq 10^9, $ 每次操作的 \(x\) 和 \(y\) 分别互不相同。
首先,我们容易得出各种\(O(n \log ^ 2n)\)的数据结构做法。然而,它们并没有太大的启发意义。
考虑离线下来,处理每个点对所有操作的贡献。
考虑求出每个点和操作最后是被哪个操作控制的。也就是能直接覆盖这个点(或操作)的操作中时间最早的。这样会形成森林的结构。显然,一个点只会对它的祖先产生贡献。而它对某个祖先\(v\)产生贡献的冲要条件就是在它到\(v\)的路径上没有比\(v\)更早的操作。
求这个森林可以使用扫描线。按\(y\)从上往下扫描,每加入一个操作就删去在它前面的出现时间晚于它的操作。这可以用set来维护。
剩下的部分可以按时间从前往后枚举所有操作,每次答案就是它的子树和,然后切断它与父亲的边。方便起见,可以用时间倒流的技巧,就相当与每次合并一个点和它的父亲。用并查集维护即可。
时间复杂度\(O(n \log n)\)。
#include <bits/stdc++.h>
using namespace std;
#define gc() getchar()
template <typename tp>
inline void read(tp& x) {
x = 0; char tmp; bool key = 0;
for (tmp = gc() ; !isdigit(tmp) ; tmp = gc())
key = (tmp == '-');
for ( ; isdigit(tmp) ; tmp = gc())
x = (x << 3) + (x << 1) + (tmp ^ '0');
if (key) x = -x;
}
const int N = 300010, INF = 0x3f3f3f3f;
struct edge {
int la,b;
} con[N << 1];
int tot,fir[N << 1];
void add(int from,int to) {
con[++tot] = (edge) {fir[from],to};
fir[from] = tot;
}
struct data {
int x,y,v;
bool operator < (const data& a) const {
return y > a.y;
}
} dat[N << 1];
int n,m,cnt,fa[N],val[N],uni[N],ans[N];
int getfa(int pos) {
return pos == uni[pos] ? pos : uni[pos] = getfa(uni[pos]);
}
typedef pair<int,int> pii;
set<pii> st;
set<pii> :: iterator t, t1;
void ins(int x,int y) {
t = st.insert(pii(x,y)).first;
while (t != st.begin()) {
t1 = t;
-- t1;
if (t1 -> second < y) break;
st.erase(t1);
}
}
int ask(int p) {
return st.upper_bound(pii(p+1,0))->second;
}
int main() {
read(n);
for (int i = 1, x, y ; i <= n ; ++ i) {
read(x), read(y);
-- x, -- y;
dat[++cnt] = (data) {x,y,0};
}
read(m);
for (int i = 1, x, y ; i <= m ; ++ i) {
read(x), read(y);
dat[++cnt] = (data) {x,y,i};
}
dat[++cnt] = (data) {INF,INF,m+1};
sort(dat+1,dat+cnt+1);
for (int i = 1, las = 1, tmp ; i <= cnt ; ++ i) {
if (dat[i].y != dat[las].y) {
for (int j = las ; j < i ; ++ j)
if (dat[j].v) ins(dat[j].x, dat[j].v);
las = i;
}
tmp = ask(dat[i].x);
if (dat[i].v) fa[dat[i].v] = tmp;
else ++ val[tmp];
}
for (int i = 1 ; i <= m ; ++ i)
uni[i] = i;
for (int i = m ; i >= 1 ; -- i) {
ans[i] = val[getfa(i)];
uni[getfa(i)] = getfa(fa[i]);
val[getfa(fa[i])] += ans[i];
}
for (int i = 1 ; i <= m ; ++ i)
printf("%d\n",ans[i]);
return 0;
}
小结:这是一道技巧性比较强的数据结构题。利用询问间的关系解题的思路,还是有启发意义的。
【做题】CERC2017B. Buffalo Barricades——时间倒流的更多相关文章
- LCT做题笔记
最近几天打算认真复习LCT,毕竟以前只会板子.正好也可以学点新的用法,这里就用来写做题笔记吧.这个分类比较混乱,主要看感觉,不一定对: 维护森林的LCT 就是最普通,最一般那种的LCT啦.这类题目往往 ...
- ACM 做题过程中的一些小技巧。
ACM做题过程中的一些小技巧. 1.一般用C语言节约空间,要用C++库函数或STL时才用C++; cout.cin和printf.scanf最好不要混用. 2.有时候int型不够用,可以用long l ...
- [日记&做题记录]-Noip2016提高组复赛 倒数十天
写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...
- SDOI2014 R1做题笔记
SDOI2014 R1做题笔记 经过很久很久的时间,shzr又做完了SDOI2014一轮的题目. 但是我不想写做题笔记(
- SDOI2016 R1做题笔记
SDOI2016 R1做题笔记 经过很久很久的时间,shzr终于做完了SDOI2016一轮的题目. 其实没想到竟然是2016年的题目先做完,因为14年的六个题很早就做了四个了,但是后两个有点开不动.. ...
- 【做题】spoj4060 A game with probability——dp
赛前做题时忽然发现自己概率博弈类dp很弱,心好慌.(获胜概率或最优解期望) 于是就做了这道题,续了特别久. 一开始列dp式子的时候就花了很长时间,首先搞错了两次,然后忘记了根据上一轮dp值直接确定选什 ...
- noip做题记录+挑战一句话题解?
因为灵巧实在太弱辽不得不做点noip续下命QQAQQQ 2018 积木大赛/铺设道路 傻逼原题? 然后傻逼的我居然检查了半天是不是有陷阱最后花了差不多一个小时才做掉我做过的原题...真的傻逼了我:( ...
- 小学生轻松做题App
作业链接:https://edu.cnblogs.com/campus/fzzcxy/2016SE/homework/2180 原型模型设计工具:墨刀 原型模型链接:https://modao.cc/ ...
- BZOJ做题记录[0512~?]
觉得做一道开一篇真不好...好多想找的东西都被刷下去了... 至于?的日期究竟到什么时候...还是看心情...但是估计不会超过七天吧 最后更新时间:05/19 10:42 [05/14 10:56]我 ...
随机推荐
- Python3.0科学计算学习之绘图(二)
(1) np.mashgrid()函数:-----生成网络点坐标矩阵,可以是二维网络矩阵,也可以是三维网络矩阵.其中,每个交叉点就是网络点,描述这些网络点的矩阵就是坐标矩阵(横坐标矩阵X中的每个元素与 ...
- notify.min.js
/*! * @wcjiang/notify v2.0.11 * JS achieve the browser title flashing , scrolling, voice prompts , c ...
- 60.Vue:将px转化为rem,适配移动端
1.下载lib-flexible 我使用的是vue-cli+webpack,所以是通过npm来安装的 npm i lib-flexible --save 2.引入lib-flexible 在main. ...
- PHP洗牌、猴子选大王两个小算法
<一>洗牌算法 /** *洗牌算法washCard *@param $cardNum *@return array */ function washCard($cardNum) { $ca ...
- XML文件的读取
<?xml version="1.0" encoding="gbk"?> <!--设置编码格式为gbk--> <!DOCTYPE ...
- [Docker] sh: docker-compose: not found
有点坑爹,在使用 alpine 镜像的时候,明明在里面安装了docker-compose,/usr/local/bin/docker-compose也是存在的,却报 sh: docker-compo ...
- 论文速读(Chuhui Xue——【arxiv2019】MSR_Multi-Scale Shape Regression for Scene Text Detection)
Chuhui Xue--[arxiv2019]MSR_Multi-Scale Shape Regression for Scene Text Detection 论文 Chuhui Xue--[arx ...
- 目标检测方法——R-FCN
R-FCN论文阅读(R-FCN: Object Detection via Region-based Fully Convolutional Networks ) 目录 作者及相关链接 方法概括 方法 ...
- 配置nginx + keepalived 双主模式(双机互为主备)
- 媒体查询@media 屏幕适配
@media(max-width: 1199px){.banner{height: 400px;}}1.6倍@media(min-width: 1200px) and (max-width: 1365 ...