bzoj4448(LCT)
来源:互联网 发布:打车软件 编辑:程序博客网 时间:2024/06/05 06:51
题面
题意是给你一棵树,在每个时刻标记一个点,或者问一条路径有多少个点在C时间前被标记了及路径长度。
这题好在可以离线,按时间排序后就取消了时间限制,操作变成标记一个点,询问就是问一条路径有几个点被标记了及路径长度。不会LCA,歧视树剖的我就水了棵LCT。
单点标记就把该点Splay到根,然后标记。
路径询问就分别Evert和Access两个端点,把路径放到一棵Splay上,在根上就可以得到这条路径的信息了。
#include <iostream>#include <fstream>#include <algorithm>#include <cmath>#include <ctime>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;#define mmst(a, b) memset(a, b, sizeof(a))#define mmcp(a, b) memcpy(a, b, sizeof(b))typedef long long LL;const int N=200100;int n,cnt,m;int ans[N],len[N];struct yy{ int ops,num,tim,u,v;}f[N];bool cmp(yy x,yy y){ if(x.tim==y.tim) return x.ops>y.ops; return x.tim<y.tim;}struct tree{ tree *c[2],*f,*pp; int a,sum,siz; bool flip; int d(){return f->c[1]==this;} void sc(tree *x,int d){(c[d]=x)->f=this;}}nil[N],*ro[N];tree *newtree(){ nil[++cnt]=nil[0]; nil[cnt].siz=1; return nil+cnt;}void up(tree *x){ x->sum=x->a+x->c[0]->sum+x->c[1]->sum; x->siz=x->c[0]->siz+x->c[1]->siz+1;}void down(tree *x){ if(!x->flip) return; swap(x->c[0],x->c[1]); if(x->c[0]!=nil) x->c[0]->flip^=1; if(x->c[1]!=nil) x->c[1]->flip^=1; x->flip=0;}void work(tree *x){ if(x->f!=nil) work(x->f); down(x);}void zig(tree *x){ tree *y=x->f; int d=x->d(); y->sc(x->c[!d],d); if(y->f==nil) x->f=nil; else y->f->sc(x,y->d()); x->sc(y,!d); up(y); up(x); x->pp=y->pp; y->pp=nil;}void splay(tree *x){ work(x); for(tree *y;x->f!=nil;) { y=x->f; if(y->f!=nil) (x->d() ^ y->d()) ? zig(x) : zig(y); zig(x); }}void Access(tree *x){ tree *y=nil; while(x!=nil) { splay(x); if(x->c[1]!=nil) { x->c[1]->f=nil; x->c[1]->pp=x; } x->c[1]=y; if(y!=nil) y->f=x; up(x); y->pp=nil; y=x; x=x->pp; }}void Evert(tree *x){ Access(x); splay(x); x->flip^=1;}int main(){ nil->c[0]=nil->c[1]=nil->f=nil->pp=nil; cin>>n; for(int i=1;i<=n;i++) ro[i]=newtree(); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); if(x) ro[i]->pp=ro[x]; } cin>>m; for(int i=1;i<=m;i++) { f[i].num=i; scanf("%d",&f[i].ops); if(f[i].ops==2) { scanf("%d",&f[i].u); f[i].tim=i; } else { scanf("%d%d%d",&f[i].u,&f[i].v,&f[i].tim); f[i].tim=i-f[i].tim-1; } } sort(f+1,f+m+1,cmp); for(int i=1;i<=m;i++) { if(f[i].ops==2) { splay(ro[f[i].u]); ro[f[i].u]->a=1; up(ro[f[i].u]); } else { Evert(ro[f[i].u]); Access(ro[f[i].v]); splay(ro[f[i].v]); ans[f[i].num]=ro[f[i].v]->sum; len[f[i].num]=ro[f[i].v]->siz; } } for(int i=1;i<=m;i++) if(len[i]) printf("%d %d\n",len[i],ans[i]); return 0;}
阅读全文
0 0
- bzoj4448(LCT)
- LCT
- LCT
- LCT
- Lct
- 【Bzoj4448】情报传递
- bzoj4448: [Scoi2015]情报传递
- 【bzoj4448】【SCOI2015】情报传递
- bzoj4448 [Scoi2015]情报传递 树链剖分+树状数组
- LCT小结
- LCT模版
- hdu2475 LCT
- poj2763 LCT
- hdu4010 LCT
- hdu5052 LCT
- LCT系列
- hdu5002 LCT
- LCT练习
- Pareto(帕雷托)相关知识
- 云计算
- 解决(Ubuntu)终端 命令提示符太长
- 【数据库】——再次认识
- 比《恐怖游轮》更可怕的是什么?
- bzoj4448(LCT)
- 学生系统优化
- JSON必备基础知识
- 剑指offerQuestion9
- 2017杰作: Oracle sql 分页查询
- 机器学习-The CIFAR-10 dataset下载
- python 读写文件
- HashMap和HashTable的区别
- 图片C#基于模板获取位置