zoukankan      html  css  js  c++  java
  • P3384 树链剖分模板

    复习(预习)一下树链剖分

    Reference:https://www.cnblogs.com/chinhhh/p/7965433.html

    
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+5;
    int tr[maxn<<2],lazy[maxn<<2];
    int size[maxn],dep[maxn],fa[maxn],top[maxn],w[maxn],wt[maxn],son[maxn],id[maxn];
    int n,m,r,times=0;
    long long mod;
    ll add(ll a,ll b){
    	return (a+b+mod)%mod;
    }
    ll mul(ll a,ll b){
    	return a*b%mod;
    }
    ll res=0;
    void push_down(int o,int len){
    	if(lazy[o]){
    		lazy[o<<1]=add(lazy[o<<1],lazy[o]);
    		lazy[o<<1|1]=add(lazy[o<<1|1],lazy[o]);
    		tr[o<<1]=add(tr[o<<1],mul(lazy[o],len-len/2));
    		tr[o<<1|1]=add(tr[o<<1|1],mul(lazy[o],len/2));
    		lazy[o]=0;
    	}
    }
    void build(int o,int l,int r){
    	if(l==r){
    		tr[o]=wt[l];
    		return ;
    	}
    	int mid=l+r>>1;
    	build(o<<1,l,mid);
    	build(o<<1|1,mid+1,r);
    	tr[o]=add(tr[o<<1],tr[o<<1|1]);
    }
    void query(int o,int l,int r,int x,int y){
    	if(x<=l&&y>=r){
    		res=add(res,tr[o]);
    		return ;
    	}
    	else {
    		int mid=l+r>>1;
    		push_down(o,r-l+1);
    		if(mid>=x)query(o<<1,l,mid,x,y);
    		if(mid<y)query(o<<1|1,mid+1,r,x,y);
    	}
    }
    void update(int o,int l,int r,int x,int y,int k){
    	if(x<=l&&y>=r){
    		lazy[o]=add(lazy[o],k);
    		tr[o]=add(tr[o],mul(k,r-l+1));
    	}
    	else {
    		push_down(o,r-l+1);
    		int mid=l+r>>1;
    		if(mid>=x)update(o<<1,l,mid,x,y,k);
    		if(mid<y)update(o<<1|1,mid+1,r,x,y,k);
    		tr[o]=add(tr[o<<1],tr[o<<1|1]);
    	}
    }
    
    
    struct Node{
    	int next,to;
    }edge[2*maxn];
    int head[maxn];
    int cnt=0;
    void add_edge(int x,int y){
    	edge[cnt].next=head[x];
    	edge[cnt].to=y;
    	head[x]=cnt++;
    }
    void dfs1(int x){
    	size[x]=1,dep[x]=dep[fa[x]]+1;
    	for(int i=head[x];i!=-1;i=edge[i].next){
    		int y=edge[i].to;
    		if(y!=fa[x]){
    			fa[y]=x;dfs1(y);size[x]+=size[y];
    			if(size[son[x]]<size[y]){
    				son[x]=y;
    			}
    		}
    	}
    }
    void dfs2(int x,int tp){
    	top[x]=tp;id[x]=++times;wt[times]=w[x];
    	if(son[x]==0)return ;
    	dfs2(son[x],tp);
    	for(int i=head[x];i!=-1;i=edge[i].next){
    		int y=edge[i].to;
    		if(y!=fa[x]&&y!=son[x]){
    			dfs2(y,y);
    		}
    	}
    }
    int qRange(int x,int y){
    	int ans=0;
    	while(top[x]!=top[y]){
    		if(dep[top[x]]<dep[top[y]])swap(x,y);
    		res=0;
    		query(1,1,n,id[top[x]],id[x]);
    		ans=add(ans,res);
    		x=fa[top[x]];
    	}
    	if(dep[x]>dep[y])swap(x,y);
    	res=0;
    	query(1,1,n,id[x],id[y]);
    	ans=add(ans,res);
    	return ans;
    }
    void updRange(int x,int y,int k){
    	while(top[x]!=top[y]){
    		if(dep[top[x]]<dep[top[y]])swap(x,y);
    		update(1,1,n,id[top[x]],id[x],k);
    		x=fa[top[x]];
    	}
    	if(dep[x]>dep[y])swap(x,y);
    	update(1,1,n,id[x],id[y],k);
    }
    int qSon(int x){
    	res=0;
    	query(1,1,n,id[x],id[x]+size[x]-1);
    	return res;
    }
    void updSon(int x,int k){
    	update(1,1,n,id[x],id[x]+size[x]-1,k);
    }
    int main(){
    	scanf("%d%d%d%lld",&n,&m,&r,&mod);
    	head[0]=-1;
    	for(int i=1;i<=n;i++)scanf("%d",&w[i]),head[i]=-1;
    	for(int i=1;i<n;i++){
    		int x,y;scanf("%d%d",&x,&y);add_edge(x,y);add_edge(y,x);
    	}
    	dfs1(r);
    	dfs2(r,r);
    	build(1,1,n);
    	while(m--){
    		int x,y,z;
    		int op;
    		scanf("%d",&op);
    		if(op==1){
    			scanf("%d%d%d",&x,&y,&z);
    			updRange(x,y,z);
    		}
    		if(op==2){
    			scanf("%d%d",&x,&y);
    			printf("%d
    ",qRange(x,y));
    		}
    		if(op==3){
    			scanf("%d%d",&x,&y);
    			updSon(x,y);
    		}
    		if(op==4){
    			scanf("%d",&x);
    			printf("%d
    ",qSon(x));
    		}
    	}
    
    }
    
    
  • 相关阅读:
    文件复制
    linux 计划任务
    mysql查询权限的用户名密码
    mysql导入导出及复制
    windowslucene安装配置
    apache+php32位平台安装
    文件移动
    mysql查询权限的用户名密码
    取树状结构的某个值下的所有记录
    今天发生了个有趣的排序
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/12962411.html
Copyright © 2011-2022 走看看