zoukankan      html  css  js  c++  java
  • bzoj2631

      题目不难理解,模型也就是比较经典的LCT;

     但需要注意乘法标记和加法标记的下传。

    (我难道会告诉你我因此wa了4,5遍吗?);

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    #define LL unsigned int
    #define FILE "dealing"
    #define up(i,j,n) for(LL i=(j);i<=(n);i++)
    LL read(){
    	int ch=getchar(),f=1,x=0;
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch<='9'&&ch>='0')x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return f*x;
    }
    const LL maxn=100100,inf=1000000000,mod=51061;
    LL n,m;
    LL fa[maxn],c[maxn][2],v[maxn],delet[maxn],w[maxn],ch[maxn],q[maxn],top,rev[maxn],siz[maxn];
    struct node{LL y,next;}e[maxn<<1];
    LL len=0,linkk[maxn];
    void insert(LL x,LL y){e[++len].y=y;e[len].next=linkk[x];linkk[x]=len;}
    bool isroot(LL o){return c[fa[o]][1]!=o&&c[fa[o]][0]!=o;}
    void updata(LL x){v[x]=(v[c[x][1]]+v[c[x][0]]+w[x])%mod;siz[x]=(siz[c[x][0]]+siz[c[x][1]]+1)%mod;}
    void reve(LL x){swap(c[x][0],c[x][1]);rev[x]^=1;}
    void dele(LL x,LL t){delet[x]=(delet[x]+t)%mod,v[x]=(v[x]+t*siz[x])%mod,w[x]=(w[x]+t)%mod;}
    void cheng(LL x,LL c){v[x]=(v[x]*c)%mod,w[x]=(w[x]*c)%mod,ch[x]=(ch[x]*c)%mod,delet[x]=(delet[x]*c)%mod;}
    void downdata(LL x){
    	if(ch[x]!=1)cheng(c[x][0],ch[x]),cheng(c[x][1],ch[x]),ch[x]=1;
    	if(delet[x])dele(c[x][0],delet[x]),dele(c[x][1],delet[x]),delet[x]=0;
    	if(rev[x])rev[x]^=1,reve(c[x][0]),reve(c[x][1]);
    }
    void rotate(LL x){
    	LL y=fa[x],z=fa[y];
    	LL d=c[y][1]==x;
    	if(!isroot(y))c[z][c[z][1]==y]=x;
    	fa[x]=z,fa[y]=x;fa[c[x][d^1]]=y;
    	c[y][d]=c[x][d^1],c[x][d^1]=y;
    	updata(y);updata(x);
    }
    void splay(LL x){
    	q[++top]=x;
    	for(LL i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
    	while(top)downdata(q[top--]);
    	while(!isroot(x)){
    		LL 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(LL x){
    	for(LL t=0;x;t=x,x=fa[x])splay(x),c[x][1]=t,updata(x);
    }
    void makeroot(LL x){
    	access(x),splay(x),reve(x);
    }
    void link(LL x,LL y){
    	makeroot(x),fa[x]=y;
    }
    void cut(LL x,LL y){
    	makeroot(x);access(y);splay(y);fa[x]=0;c[y][0]=0;
    }
    void build(LL x){
    	ch[x]=siz[x]=v[x]=w[x]=1;
    	for(LL i=linkk[x];i;i=e[i].next){
    		if(fa[x]==e[i].y)continue;
    		fa[e[i].y]=x;
    		build(e[i].y);
    	}
    }
    int main(){
    	freopen(FILE".in","r",stdin);
    	freopen(FILE".out","w",stdout);
    	n=read(),m=read();
    	up(i,1,n-1){
    		LL x=read(),y=read();
    		insert(x,y);insert(y,x);
    	}
    	build(1);
    	char s[10];LL x,y,c,u1,u2,v1,v2;
    	while(m--){
    		scanf("%s",s);
    		if(s[0]=='+'){
    			x=read(),y=read(),c=read();
    			makeroot(x),access(y),splay(y);
    			dele(y,c);
    		}
    		if(s[0]=='-'){
    			u1=read(),v1=read(),u2=read(),v2=read();
    			cut(u1,v1);
    			link(u2,v2);
    		}
    		if(s[0]=='*'){
    			x=read(),y=read(),c=read();
    			makeroot(x);access(y);splay(y);
    			cheng(y,c);
    		}
    		if(s[0]=='/'){
    			x=read(),y=read();
    			makeroot(x);access(y);splay(y);
    			printf("%d
    ",v[y]);
    		}
    	}
    	printf("%d
    ",clock());
    	return 0;
    }
    

      

  • 相关阅读:
    Javascript正则表达式详解转载
    转载Sqlserver2005 存储过程分页
    转载手把手教你用C#打包应用程序
    学习内容
    用C#实现将HTML文件转换为CHM文件(转)
    C# Windows服务添加安装程序
    sql 2008评估期已过有关如何升级,企业试用版到期,升级为企业版+sql2008破解
    iis不能启动是什么原因?错误提示:“提示服务器没有及时相应启动或控制请求”
    .NET 获取数据库中所有表名的方法
    如何获取Dynamics当前登录的用户的GUID,进而获取用户的信息
  • 原文地址:https://www.cnblogs.com/chadinblog/p/6323278.html
Copyright © 2011-2022 走看看