BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 【LCT维护深度】

LCT板题。
然而我还是WA到自闭。
对着大数据调。。。(最后还是自己造小数据)
结果发现当LCT需要维护深度的时候不能随便beroot!!
一旦beroot之后深度关系就会变!!
所以把link,cut操作统统改掉。。变成直接断边。

Code(完整模板(很多函数都没用)):

#include
#include
#include
#include
#define maxn 200005
using namespace std;
template<class T>inline void read(T &a){
    char c;bool f=0;
    while(!isdigit(c=getchar())) if(c=='-') f=1;
    for(a=c-'0';isdigit(c=getchar());a=a*10+c-'0');
    if(f) a=-a;
}
namespace LCT{
    int ch[maxn][2],fa[maxn],sum[maxn],v[maxn];
    bool rev[maxn];
    #define il inline
    #define pa fa[x]
    il bool isc(int x){return ch[pa][1]==x;}
    il bool isr(int x){return ch[pa][0]!=x&&ch[pa][1]!=x;}
    il void pd(int x){
        if(rev[x]){
            swap(ch[x][0],ch[x][1]),rev[x]=0;
            if(ch[x][0]) rev[ch[x][0]]^=1;
            if(ch[x][1]) rev[ch[x][1]]^=1;
        }
    }
    il void pdpath(int x){if(!isr(x)) pdpath(pa);pd(x);}
    il void upd(int x){
        sum[x]=sum[ch[x][0]]+sum[ch[x][1]]+v[x];
    }
    il void rot(int x){
        int y=fa[x],z=fa[y],c=isc(x);
        if(!isr(y)) ch[z][ch[z][1]==y]=x;
        (ch[y][c]=ch[x][!c])&&(fa[ch[y][c]]=y);
        fa[ch[x][!c]=y]=x,fa[x]=z;
        upd(y),upd(x);
    }
    il void splay(int x){
        pdpath(x);
        for(;!isr(x);rot(x))
            if(!isr(pa)) rot(isc(pa)==isc(x)?pa:x);
    }
    il int access(int x,int y=0){
        for(;x;x=fa[y=x]) splay(x),ch[x][1]=y,upd(x);
        return y;
    }
    il void bert(int x){
        access(x),splay(x),rev[x]^=1;
    }
    il int sert(int x){
        access(x),splay(x);
        for(;ch[x][0];x=ch[x][0]);
        return x;
    }
    il void link(int x,int y){
        bert(x);if(sert(y)==x) return;
        fa[x]=y;
    }
    il void cut(int x,int y){
        bert(x);
        if(sert(y)!=x||fa[x]!=y||ch[x][1]!=0) return;
        fa[x]=ch[y][0]=0;
        upd(y);
    }
    il void modify(int x,int y){
        splay(x),v[x]=y;
        upd(x);
    }
    il void split(int x,int y){
        bert(x),access(y),splay(y);
    }
    il int qsum(int x,int y){split(x,y);return sum[y];}
}
using namespace LCT;
int n,m,x,y,a[maxn],op;
int main()
{
    //freopen("1.in","r",stdin);
    //freopen("1.out","w",stdout);
    read(n);
    for(int i=1;i<=n;i++) sum[i]=v[i]=1;
    for(int i=1;i<=n;i++) {read(a[i]);if(i+a[i]<=n) link(i,i+a[i]);}
    read(m);
    while(m--){
        read(op),read(x),x++;
        if(op==1) access(x),splay(x),printf("%d\n",sum[x]);
        else{
            read(y);
            if(x+a[x]<=n) access(x),splay(x),ch[x][0]=fa[ch[x][0]]=0,upd(x);
            if(x+(a[x]=y)<=n) splay(x),fa[x]=x+a[x];
        }
    }
}

你可能感兴趣的:(LCT)