zoukankan      html  css  js  c++  java
  • [BZOJ 2759] 一个动态树好题

    这题确实很好.

    题解方面,网上有许多不错的题解,所以就不说了.

    这题很需要注意细节.

    #include<cstdio>
    using namespace std;
    #define ll long long
    #define up(i,j,n) for(int i=j;i<=n;i++)
    #define db long double 
    #define pii pair<int,int>
    #define pb push_back
    #define FILE "dealing"
    template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;}
    template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;}
    template<class T> inline T squ(T a){return a*a;}
    const int maxn=210000+10,mod=10007,base=23;
    int read(){
        int x=0,f=1,ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
        return x*f;
    }
    struct Node{
    	int y,next,v;
    }e[maxn];int len,linkk[maxn];
    void insert(int x,int y,int v){
    	e[++len].y=y;
    	e[len].next=linkk[x];
    	linkk[x]=len;
    	e[len].v=v;
    }
    int n,m;
    int fa[maxn],sf[maxn],c[maxn][2];
    bool isroot(int x){
    	return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
    }
    
    struct node{
    	int k,b;
    	node(int k=1,int b=0):k(k),b(b){}
    }li[maxn],sum[maxn];
    node operator+(const node& a,const node& b){
    	node c;
    	c.k=a.k*b.k%mod;
    	c.b=(a.b*b.k%mod+b.b)%mod;
    	return c;
    }
    void updata(int x){
    	sum[x]=sum[c[x][0]]+li[x]+sum[c[x][1]];
    }
    void rotate(int x){
    	int y=fa[x],z=fa[y],d=c[y][1]==x;
    	if(!isroot(y))c[z][c[z][1]==y]=x;
    	fa[y]=x;fa[x]=z;if(c[x][d^1])fa[c[x][d^1]]=y;
    	c[y][d]=c[x][d^1],c[x][d^1]=y;
    	updata(y);updata(x);
    }
    void splay(int x){
    	if(!x)return;
    	while(!isroot(x)){
    		int y=fa[x],z=fa[y];
    		if(!isroot(y)){
    			if(c[y][1]==x^c[z][1]==y)rotate(x);
    			else rotate(y);
    		}
    		rotate(x);
    	}
    }
    void access(int x){
    	for(int t=0;x;t=x,x=fa[x]){
    		splay(x);
    		c[x][1]=t;
    		updata(x);
    	}
    }
    int root,vis[maxn];
    void dfs(int x,int fa){
    	vis[x]=1;
    	for(int i=linkk[x];i;i=e[i].next){
    		if(e[i].y==fa)continue;
    		if(!vis[e[i].y])dfs(e[i].y,x);
    		else root=x;
    	}
    }
    int inv[maxn];
    int getroot(int x){
    	access(x);splay(x);
    	while(c[x][0])x=c[x][0];
    	return x;
    }
    int getl(int x){
    	access(x);splay(x);
    	x=c[x][0];while(c[x][1])x=c[x][1];
    	return x;
    }
    int tk[maxn];
    int main(){
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    	n=read();
    	up(i,1,n){
    		li[i].k=read();
    		fa[i]=read();
    		li[i].b=read();
    		sum[i]=li[i];
    		insert(i,fa[i],1);
    		insert(fa[i],i,-1);
    		tk[i]=fa[i];
    	}
    	up(i,1,n){
    		if(vis[i])continue;
    		root=0;
    		dfs(i,0);
    		sf[root]=fa[root];
    		fa[root]=0;
    	}
    	m=read();
    	inv[0]=inv[1]=1;
    	for(int i=2;i<mod;i++)inv[i]=(mod-(mod/i)*inv[mod%i]%mod)%mod;
    	up(i,1,m){
    		char s;
    		scanf(" %c",&s);
    		if(s=='A'){
    			int x=read();
    			int root=getroot(x),y=sf[root];
    			access(y);splay(y);
    			node b=sum[y];
    			if(b.k==1){
    				if(b.b==0)printf("%d
    ",-2);
    				else printf("-1
    ");
    			}
    			else {
    				int key=(mod-b.b)%mod*inv[(b.k-1+mod)%mod]%mod;
    				access(x);splay(x);
    				printf("%d
    ",(sum[x].k*key%mod+sum[x].b)%mod);
    			}
    		}
    		else {
    			int x=read(),k=read(),p=read(),b=read();
    			int ro=getroot(x);
    			li[x]=node(k,b);
    			updata(x);
    			if(tk[x]==p)continue;
    			tk[x]=p;
    			if(ro==x){
    				sf[ro]=0;
    				int ro2=getroot(p);
    				if(ro2==ro)sf[ro]=p;
    				else {
    					access(ro);splay(ro);
    					fa[ro]=p;
    				}
    			}
    			else {
    				int w=getl(x);
    				access(x);splay(w);
    				c[w][1]=fa[x]=0;updata(w);
    				int y=sf[ro];
    				int ro2=getroot(y);
    				if(ro2!=ro){
    					access(ro);
    					splay(ro);
    					fa[ro]=y;
    					sf[ro]=0;
    				}
    				int ro3=getroot(p);
    				access(x);
    				splay(x);
    				if(ro3!=x)fa[x]=p;
    				else sf[x]=p;
    			}
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    HDU 5640 King's Cake
    HDU 5615 Jam's math problem
    HDU 5610 Baby Ming and Weight lifting
    WHU1604 Play Apple 简单博弈
    HDU 1551 Cable master 二分
    CodeForces659C Tanya and Toys map
    Codeforces 960E 树dp
    gym 101485E 二分匹配
    Codeforces 961E 树状数组,思维
    Codeforces Round #473 (Div. 2) D 数学,贪心 F 线性基,模板
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6858517.html
Copyright © 2011-2022 走看看