Codeforces 605D - Board Game(树状数组套 set)
事实上是一道非常容易的题
很容易想到如果 \(c_i\geq a_j\) 且 \(d_i\geq b_j\) 就连一条 \(i\to j\) 的边表示用完 \(i\) 之后可以用 \(j\)。然后跑 BFS。
直接跑复杂度是 \(n^2\),不过发现一个性质,那就是每个点最多被访问一次,故考虑用数据结构优化 BFS 的过程,具体来说,用树状数组套 set 维护所有 \((a_i,b_i)\) 的坐标,当访问到某个 \(j\) 时候就直接在树状数组套 set 上找出全部满足 \(a_i\leq c_j,b_i\leq d_j\) 的 \(i\) 并将其压入队列,并直接将这些点从 set 中删除。注意到每个点会恰好被删除一次,故总删除次数是线性的,再加上树状数组套 set 本身的 2log,复杂度 \(n\log^2n\)。
记得之前做过一道什么数据结构优化二分图染色的题来着的?这题思想似乎与那题差不多,都是利用每个点最多被访问一次这个性质,用数据结构优化暴力的过程(不过似乎这题比那题还容易一些)。
上帝不要惩罚我刷水题/kk
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXN=1e5;
int n,a[MAXN+5],b[MAXN+5],c[MAXN+5],d[MAXN+5];
int key[MAXN*2+5],cnt=0,uni[MAXN*2+5],num=0;
set<pii> st[MAXN*2+5];
void insert(int x,int y,int z){
for(int i=x;i<=num;i+=(i&(-i))) st[i].insert(mp(y,z));
}
void del(int x,int y,int z){
for(int i=x;i<=num;i+=(i&(-i))) st[i].erase(st[i].find(mp(y,z)));
}
vector<int> query(int x,int y){
vector<int> ret;
for(int i=x;i;i&=(i-1)){
set<pii>::iterator t=st[i].lower_bound(mp(y+1,0));
for(set<pii>::iterator it=st[i].begin();it!=t;++it){
ret.pb(it->se);
}
} return ret;
}
int dis[MAXN+5],from[MAXN+5];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&a[i],&b[i],&c[i],&d[i]);
key[++cnt]=a[i];key[++cnt]=c[i];
} key[++cnt]=0;sort(key+1,key+cnt+1);key[0]=-1;
for(int i=1;i<=cnt;i++) if(key[i]!=key[i-1]) uni[++num]=key[i];
for(int i=1;i<=n;i++){
a[i]=lower_bound(uni+1,uni+num+1,a[i])-uni;
c[i]=lower_bound(uni+1,uni+num+1,c[i])-uni;
}
for(int i=1;i<=n;i++) insert(a[i],b[i],i);
memset(dis,-1,sizeof(dis));queue<int> q;
vector<int> v=query(1,0);
for(int i=0;i<v.size();i++) dis[v[i]]=1,q.push(v[i]),del(a[v[i]],b[v[i]],v[i]);
while(!q.empty()){
int x=q.front();q.pop();v=query(c[x],d[x]);
for(int i=0;i<v.size();i++){
int t=v[i];dis[t]=dis[x]+1;from[t]=x;q.push(t),del(a[t],b[t],t);
}
}
if(dis[n]==-1) printf("-1\n");
else{
printf("%d\n",dis[n]);vector<int> v;
for(int i=n;i;i=from[i]) v.pb(i);
reverse(v.begin(),v.end());
for(int i=0;i<v.size();i++) printf("%d ",v[i]);
}
return 0;
}
Codeforces 605D - Board Game(树状数组套 set)的更多相关文章
- Codeforces 1139F Dish Shopping 树状数组套平衡树 || 平衡树
Dish Shopping 将每个物品拆成p 和 s 再加上人排序. 然后问题就变成了, 对于一个线段(L - R), 问有多少个(li, ri)满足 L >= li && R ...
- Codeforces Round #404 (Div. 2) E. Anton and Permutation(树状数组套主席树 求出指定数的排名)
E. Anton and Permutation time limit per test 4 seconds memory limit per test 512 megabytes input sta ...
- BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树
[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> ...
- 【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings
谁再管这玩意叫树状数组套主席树我跟谁急 明明就是树状数组的每个结点维护一棵动态开结点的权值线段树而已 好吧,其实只有一个指针,指向该结点的权值线段树的当前结点 每次查询之前,要让指针指向根结点 不同结 ...
- BZOJ 1901 Zju2112 Dynamic Rankings ——树状数组套主席树
[题目分析] BZOJ这个题目抄的挺霸气. 主席树是第一时间想到的,但是修改又很麻烦. 看了别人的题解,原来还是可以用均摊的思想,用树状数组套主席树. 学到了新的姿势,2333o(* ̄▽ ̄*)ブ [代 ...
- 【BZOJ-1452】Count 树状数组 套 树状数组
1452: [JSOI2009]Count Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1769 Solved: 1059[Submit][Stat ...
- 【BZOJ】1901: Zju2112 Dynamic Rankings(区间第k小+树状数组套主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1901 首先还是吐槽时间,我在zoj交无限tle啊!!!!!!!!我一直以为是程序错了啊啊啊啊啊啊. ...
- BZOJ1901 - Dynamic Rankings(树状数组套主席树)
题目大意 给定一个有N个数字的序列,然后又m个指令,指令种类只有两种,形式如下: Q l r k 要求你查询区间[l,r]第k小的数是哪个 C i t 要求你把第i个数修改为t 题解 动态的区间第k ...
- bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1384 Solved: 629[Submit][Stat ...
随机推荐
- Golang通脉之面向对象
面向对象的三大特征: 封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式 继承:使得子类具有父类的属性和方法或者重新定义.追加属性和方法等 多态:不同对象中同种行为的不同实现方式 Go并不是一个纯 ...
- 【Spring】IoC容器 - Spring Bean作用域Scope(含SpringCloud中的RefreshScope )
前言 上一章学习了[依赖来源],本章主要讨论SpringBean的作用域,我们这里讨论的Bean的作用域,很大程度都是默认只讨论依赖来源为[Spring BeanDefinition]的作用域,因为在 ...
- 【UE4】类的继承层级关系
- Sobol 序列并行化的实践经验
目录 Sobol 序列并行化的实践经验 随机数发生器并行化的常见策略 Sobol 序列的原理和跳转功能 Sobol 序列并行化实践 分块策略 蛙跳策略 蛙跳策略的计算量分析 减少异或计算的技巧 分块策 ...
- try-catch-finally面试题
try catch finally 执行顺序面试题总结 执行顺序 今天牛客网遇到这个题目,做对了,但是下面的评论却很值得看看 public class TestTry { public int add ...
- 面试官问:说说你对Java函数式编程的理解
常见的面试问题 总结一下,在Java程序员的面试中,经常会被问到类似这样的问题: Java中的函数式接口是什么意思? 注解 @FunctionalInterface 的作用是什么? 实现一个函数式接口 ...
- 如何优雅的处理 accept 出现 EMFILE 的问题
通常情况下,服务端调用 accept 函数会返回一个新的文件描述符,用于和客户端之间的数据传输 在服务器的开发中,有时会遇到这种情况:当调用 accept 函数接受客户端连接,函数返回失败,对应的错误 ...
- linux exit 和 _exit的区别
今天仔细看了一下exit和_exit这两个函数的区别,实际上exit也是调用了_exit退出函数的,只不过在调用_exit之前,exit还进行了一些多余的工作,也正是因为这样,相比起来exit就没有那 ...
- cf14C Four Segments(计算几何)
题意: 给四个线段(两个端点的坐标). 判断这四个线段能否构成一个矩形.(矩形的四条边都平行于X轴或Y轴) 思路: 计算几何 代码: class Point{ public: int x,y; voi ...
- 更改mysql数据库根目录
1,查看原根目录 2,然后关闭数据库服务 3,cp -r 源根目录到目的根目录 4,修改my.cnf文件定义的根目录位置到目的根目录 5,启动数据库