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;
    }
    

      

  • 相关阅读:
    求X的N次乘方
    用辗转相除法求两个正整数的最大公约数
    求两、三个数中较大者的函数
    电文加密问题
    C#纯数学方法递归实现货币数字转换中文
    查找二维数组的查找之杨氏矩阵
    IT公司笔经面经
    排序2计数排序,桶排序
    windows Concurrency Runtimewindows的并行编程模型
    <c++ primer>第五部分 高级主题
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6858517.html
Copyright © 2011-2022 走看看