【BZOJ 2002】【Hnoi 2010】弹飞绵羊 分块||Link Cut Tree 两种方法
ShallWe,Yveh,hmy,DaD3zZ,四人吃冰糕从SLYZ超市出来后在马路上一字排开,,,吃完后发现冰糕棍上写着:“向狮子座表白:愿做你的小绵羊”,,,
好吧在这道题里我们要弹飞绵羊,有分块和lct两种方法。
分块:
#include<cmath> #include<cstdio> #define for1(i,a,n) for(int i=(a);i<=(n);i++) #define for3(i,a,n) for(int i=(a);i>=(n);i--) #define read(x) x=getint() using namespace std; inline int getint(){char c;int ret=0;for(c=getchar();c<'0'||c>'9';c=getchar());for(;c>='0'&&c<='9';c=getchar())ret=ret*10+c-'0';return ret;} const int N=200003; int n,o[N],t[N],w[N],step[N]; inline void work(int i){ int j=i+t[i]; if (j>n) w[i]=n+1,step[i]=1; if (o[i]==o[j]){ w[i]=w[j]; step[i]=step[j]+1; }else{ w[i]=j; step[i]=1; } } int main(){ read(n); for1(i,1,n) read(t[i]); int pn=floor(sqrt(n)),q,id,x,y; for1(i,1,n) o[i]=(i-1)/pn+1; for3(i,n,1) work(i); read(q); while (q--){ read(id); if (id==1){ read(x); x++; y=0; while (x<=n){ y+=step[x]; x=w[x]; } printf("%d\n",y); }else{ read(x); read(y); x++; t[x]=y; for3(i,x,1) if (o[x]==o[i]) work(i); else break; } } return 0; }
LCT(为什么我的lct的常数辣么大T_T)
#include<cstdio> #include<algorithm> #define for1(i,a,n) for(int i=(a);i<=(n);i++) #define read(x) x=getint() using namespace std; inline int getint(){char c;int ret=0;for(c=getchar();c<'0'||c>'9';c=getchar());for(;c>='0'&&c<='9';c=getchar())ret=ret*10+c-'0';return ret;} const int N=200003; struct node *null; struct node{ node(); node *fa,*ch[2]; int s; void count() {s=1+ch[0]->s+ch[1]->s;} bool pl() {return fa->ch[1]==this;} void setc(node *r,bool c) {ch[c]=r; r->fa=this;} bool check() {return fa==null||((fa->ch[0]!=this)&&(fa->ch[1]!=this));} }*rt[N]; node::node(){s=1;fa=ch[0]=ch[1]=null;} int n; inline void Build(){null=new node;null->s=0;null->ch[0]=null->ch[1]=null->fa=null;} inline void rotate(node *r){ node *f=r->fa; bool c=r->pl(); if (f->check()) r->fa=f->fa; else f->fa->setc(r,f->pl()); f->setc(r->ch[c^1],c); r->setc(f,c^1); f->count(); r->count(); } inline void splay(node *r){ for(;!r->check();rotate(r)) if (!r->fa->check()) rotate(r->fa->pl()==r->pl()?r->fa:r); r->count(); } inline void access(node *r){ for(node *c=null;r!=null;r=r->fa){ splay(r); r->setc(c,1); r->count(); c=r; } } inline void link(node *r,node *f){ access(r); splay(r); r->ch[0]->fa=null; r->ch[0]=null; r->fa=f; r->count(); } int main(){ Build(); int t,q,x,y; read(n); for1(i,1,n) rt[i]=new node; for1(i,1,n) {read(t); if (i+t<=n) rt[i]->fa=rt[i+t];} read(q); while (q--){ read(x); if (x==1){ read(y); y++; access(rt[y]); splay(rt[y]); printf("%d\n",rt[y]->s); }else{ read(x); read(y); x++; if (x+y<=n) link(rt[x],rt[x+y]); else link(rt[x],null); } } return 0; }
BeiYu的常数总是比我的要小,,本蒟蒻还得继续努力啊
NOI 2017 Bless All