【bzoj2002】【LCT】弹飞绵羊
2016-12-28 16:24
260 查看
题意:给一段序列和k[i]表示从i能弹到i+k[i],要求支持动态修改k值,查询由i点几次能被弹出序列长度
数据范围:对于100%的数据n<=200000,m<=100000
题解:首先对于一个点,可以从这个点向i+k[i]连一条边,i+k[i]>n时连向n这个点,显然一个点只向后连一条边,就是一棵树,求得答案就是i节点在以n+1为根的树中的深度
问题转化成了给一个树支持动态修改一条边连的点,求某一点的深度
问题又转化成了LCT裸题
修改先删除再插入
裸题一道,只可惜我太弱了,就因为cut的q p写反了调了一个晚上加一早晨。画了一张纸的树
直接放代码吧 样例过了基本就过了
数据范围:对于100%的数据n<=200000,m<=100000
题解:首先对于一个点,可以从这个点向i+k[i]连一条边,i+k[i]>n时连向n这个点,显然一个点只向后连一条边,就是一棵树,求得答案就是i节点在以n+1为根的树中的深度
问题转化成了给一个树支持动态修改一条边连的点,求某一点的深度
问题又转化成了LCT裸题
修改先删除再插入
裸题一道,只可惜我太弱了,就因为cut的q p写反了调了一个晚上加一早晨。画了一张纸的树
直接放代码吧 样例过了基本就过了
#include <iostream> #include <cstdio> #include <cstring> #define MAXN 200111 using namespace std; struct node{ int size,rev,num; node *ch[2],*fa; int dir(){return this==fa->ch[1];} void cnct(node *p,int d){ch[d]=p;p->fa=this;} void up(){size=ch[0]->size+ch[1]->size+1;} void down(); }tnull,*null=&tnull,*tree[MAXN]; void node::down(){ if(this==null) return; if(rev){ rev=0; if(ch[0]!=null)ch[0]->rev^=1; if(ch[1]!=null)ch[1]->rev^=1; swap(ch[0],ch[1]); } } node* getnode(int u){ node *p=new node(); p->size=1;p->rev=0;p->ch[0]=p->ch[1]=p->fa=null;p->num=u; return p; } bool isroot(node *p){ return p==null||p->fa->ch[0]!=p&&p->fa->ch[1]!=p; } void rot(node *p){ if(isroot(p)) return; int d=p->dir();node *x=p->fa; if(x==x->fa->ch[0]) x->fa->ch[0]=p; else if(x==x->fa->ch[1]) x->fa->ch[1]=p; p->fa=x->fa; x->cnct(p->ch[!d],d); p->cnct(x,!d); x->up(); } void splay(node *p){ static node *sta[MAXN];int top=0; sta[++top]=p; for(node *k=p;!isroot(k);k=k->fa) sta[++top]=k->fa; while(top) sta[top--]->down(); while(!isroot(p)){ if(isroot(p->fa)) {rot(p);break;} else if(p->dir()==p->fa->dir()) rot(p->fa),rot(p); else rot(p),rot(p); } p->up(); } void access(node *p){ node *q=null; while(p!=null){ splay(p); p->cnct(q,1); p->up(); q=p; p=p->fa; } } void mtr(node *p){ access(p); splay(p); p->rev=1; } void link(node *p,node *q){ mtr(p); p->fa=q; } void cut(node *p,node *q){ mtr(p); access(q); splay(q); q->ch[0]=q->ch[0]->fa=null; q->up(); } int query(node *p,node *q){ mtr(q); access(p); splay(p); return p->size; } int n,m; int f[MAXN]; int main(){ scanf("%d",&n); for(int i=1;i<=n+1;i++) tree[i]=getnode(i); for(int i=1;i<=n;i++){ int x; scanf("%d",&x);f[i]=x+i; if(f[i]>n+1) f[i]=n+1; link(tree[i],tree[f[i]]); } scanf("%d",&m); for(int i=1;i<=m;i++){ int a,b,c; scanf("%d",&a); if(a==1){ scanf("%d",&b);b++; printf("%d\n",query(tree[b],tree[n+1])-1); } else{ scanf("%d%d",&b,&c);b++; cut(tree[b],tree[f[b]]); f[b]=min(b+c,n+1); link(tree[b],tree[f[b]]); } } return 0; }
相关文章推荐
- [BZOJ 2096][Poi2010]Pilots
- BZOJ3275 Number (最小割)
- BZOJ2809——[Apio2012]dispatching
- BZOJ2809——[Apio2012]dispatching
- bzoj1088[SCOI2005]扫雷
- bzoj1086[SCOI2005]王室联邦
- [BZOJ1087][SCOI2005]互不侵犯King(状压)[第二题]
- bzoj 1015 正难则反+并查集
- bzoj 1787 lca
- bzoj 1022 博弈 Anti-Nim(模板)
- bzoj 1034 伪田忌赛马
- bzoj 2464 BFS【水】
- HNOI2010 bounce 弹飞绵羊 (BZOJ2002)
- 动态树之Link-Cut Trees
- [bzoj1003] [ZJOI2006]物流运输trans
- [bzoj1500][NOI2005]维修数列
- [bzoj1208] [HNOI2004]宠物收养所
- [bzoj1269][AHOI2006]文本编辑器editort
- [bzoj1503][NOI2004]郁闷的出纳员
- BZOJ 1012: [JSOI2008]最大数maxnumber