【BZOJ】2959: 长跑(lct+缩点)(暂时弃坑)

题目

传送门:QWQ

 

 

分析

  看起来就是一个支持link的东西。

  但有环,考虑缩点......

  但疯狂Tle。大概是常数卡不过去。

  行走的大常数noble_

 

代码

#include <bits/stdc++.h>
#define lc son[x][0]
#define rc son[x][1]
using namespace std;
const int maxn=150005;
int son[maxn][2],s[maxn],v[maxn],lazy[maxn],fa[maxn],st[maxn],dig[100];
int pa[maxn], belong[maxn], a[maxn];
inline int findset(int x){if(belong[x]==x) return x;else return belong[x]=findset(belong[x]);}
inline int find(int x){if(pa[x]==x) return x;else return pa[x]=find(pa[x]);}
inline int ws(int x){return son[findset(fa[x])][1]==x;}
inline int isroot(int x){int f=findset(fa[x]);return !(son[f][0]==x||son[f][1]==x);}
inline int rev(int x){lazy[x]^=1; swap(lc,rc);}
inline void pushdown(int x){
    if(!lazy[x]) return;
    if(lc) rev(lc); if(rc) rev(rc); lazy[x]=0;
}
inline void update(int x){ s[x]=s[lc]+s[rc]+v[x]; }
inline void rot(int x){
    int f=fa[x], ff=fa[f],w1=ws(x),w2=ws(fa[x]),xx=son[x][!w1];
    if(!isroot(f))son[ff][w2]=x;son[x][!w1]=f;son[f][w1]=xx;
    if(xx)fa[xx]=f;fa[f]=x;fa[x]=ff;
    update(f);update(x);
}
inline void splay(int x){
    int y=x,z=0; st[++z]=y; pushdown(x);
    while(!isroot(y)) st[++z]=y=findset(fa[y]);
    while(z) pushdown(st[z--]),fa[st[z]]=findset(fa[st[z]]);
    for(;!isroot(x);rot(x))
        if(ws(x)==ws(fa[x])&&!isroot(fa[x])) rot(fa[x]);
    update(x); 
}
inline void access(int x){
    for(int y=0;x;x=findset(fa[y=x])){
        splay(x); rc=y; if(y) fa[y]=x; update(x);
    }
}
inline void makeroot(int x){
    access(x); splay(x); rev(x);
}
inline int findroot(int x){
    access(x); splay(x);
    while(lc) pushdown(x),x=lc;
    return x;
}
inline void link(int x,int y){
    makeroot(x);
    if(findroot(y)==x) return;
    fa[x]=y;
}
inline void merge(int x,int y){
    if(!x) return;
    belong[findset(x)]=findset(y); pushdown(x);
    if(x!=y) v[y]+=v[x];
    if(lc) merge(lc,y); if(rc) merge(rc,y);
//    puts("**********************");
    lc=rc=0;
}
inline int in(){  
    char c=getchar();  
    for (;c>'9'||c<'0';c=getchar());  
    int num=0;  
    for (;c>='0'&&c<='9';c=getchar())    
     num=num*10+c-'0';  
    return num;  
} 
inline void write(int x)
{
    if (!x)
    {
        putchar('0');
        putchar('\n');
        return;
    }
    dig[0]=0;
    while (x)
    {
        dig[++dig[0]]=x%10;
        x/=10;
    }
    for (int i=dig[0];i>=1;--i) putchar(dig[i]+'0');
    putchar('\n');
}
int main(){
    int n,m; n=in();m=in();
    for(register int i= 1;i<=n;++i) v[i]=in(),pa[i]=belong[i]=i,a[i]=v[i];
    int p,x,y;
    while(m--){
        p=in();x=in();y=in();
        if(p==1){
            x=findset(x);y=findset(y);
            if(x==y) continue;
            int r1=find(x), r2=find(y);
            if(r1!=r2){
                pa[r2]=r1;
                link(x,y);
            }
            else{
                makeroot(x); access(y); splay(y);
                merge(y,y); update(y);
            }
        }
        if(p==2){
            int xx=x;
            x=findset(x);
            access(x); splay(x); v[x]+=y-a[xx]; a[xx]=y; 
            update(x);
        }
        if(p==3){
            x=findset(x); y=findset(y);
            if(find(x)!=find(y) ){
                write(-1); continue;
            }
            makeroot(x); access(y); splay(y);
            write(s[y]);
        }
    }
    return 0;
}

 

 

posted @ 2018-06-01 20:31  noble_(noblex)  阅读(132)  评论(0编辑  收藏  举报
/* */