zoukankan      html  css  js  c++  java
  • 树上和图上算法合集

    1、树链剖分

    浅谈树链剖分

    树链剖分模板

    #include<bits/stdc++.h>
    #define ll long long
    #define INF 2147483647
    #define mem(i,j) memset(i,j,sizeof(i))
    #define F(i,j,n) for(register int i=j;i<=n;i++)
    #define md p
    using namespace std;
    struct hahaha{
    	int from,to,nxt;
    }s[200010];
    int n,m,r,p,head[200010],cnt=0,pls[1000010];
    int v[100010],f[100010],son[100010];
    int dep[100010],top[100010],sz[100010];
    int id[1000010],vt[1000010],num=0;
    inline int read(){
    	int datta=0;char chchc=getchar();bool okoko=0;
    	while(chchc<'0'||chchc>'9'){if(chchc=='-')okoko=1;chchc=getchar();}
    	while(chchc>='0'&&chchc<='9'){datta=datta*10+chchc-'0';chchc=getchar();}
    	if(okoko==1)return -datta;
    	return datta;
    }
    inline void ins(int from,int to){
    	s[++cnt].from=from;
    	s[cnt].to=to;
    	s[cnt].nxt=head[from];
    	head[from]=cnt;
    }
    inline int dfs1(int from){
    	int tmp=0,tmx=0,ti=0;
    	for(int i=head[from];i;i=s[i].nxt){
    		int to=s[i].to;
    		if(to!=f[from]){
    			dep[to]=dep[from]+1;
    			f[to]=from;
    			tmp=dfs1(to);
    			sz[from]+=tmp;
    			if(tmp>tmx)
    				tmx=tmp,ti=to;
    		}
    	}
    	sz[from]++;
    	son[from]=ti;
    	return sz[from];
    }
    inline void dfs2(int from,int tp){
    	id[from]=++num,vt[num]=v[from];
    	if(son[from])
    		top[son[from]]=tp,dfs2(son[from],tp);
    	for(int i=head[from];i;i=s[i].nxt){
    		int to=s[i].to;
    		if(to!=f[from]&&to!=son[from])
    			top[to]=to,dfs2(to,to);
    	}
    }
    struct Segment_Tree{
    	#define ls u<<1
    	#define rs u<<1|1
    	#define mid ((l+r)>>1)
    	int tree[1000010];
    	void updata(int u){
    		tree[u]=(tree[ls]+tree[rs])%md;
    	}
    	void pushdown(int u,int l,int r){
    		if(!pls[u])
    			return ;
    		pls[ls]+=pls[u];
    		pls[rs]+=pls[u];
    		tree[ls]+=(mid-l+1)*(pls[u]);
    		tree[rs]+=(r-mid)*(pls[u]);
    		pls[u]=0;
    	}
    	void build_tree(int u,int l,int r){
    		if(l==r){
    			tree[u]=vt[l];
    			return ;
    		}
    		build_tree(ls,l,mid);
    		build_tree(rs,mid+1,r);
    		updata(u);
    	}
    	void change(int u,int l,int r,int x,int y,int z){
    		if(x<=l&&r<=y){
    			pls[u]+=z;
    			tree[u]+=(r-l+1)*z;
    			return ;
    		}
    		pushdown(u,l,r);
    		if(x<=mid)
    			change(ls,l,mid,x,y,z);
    		if(y>=mid+1)
    			change(rs,mid+1,r,x,y,z);
    		updata(u);
    	}
    	int ask(int u,int l,int r,int x,int y){
    		int res=0;
    		if(x<=l&&r<=y)
    			return tree[u];
    		pushdown(u,l,r);;
    		if(x<=mid)
    			res+=ask(ls,l,mid,x,y);
    		if(y>=mid+1)
    			res+=ask(rs,mid+1,r,x,y);
    		return res;
    	}
    }T;
    inline void cRange(int x,int y,int z){
    	while(top[x]!=top[y]){
    		if(dep[top[x]]<dep[top[y]])
    			swap(x,y);
    		T.change(1,1,n,id[top[x]],id[x],z);
    		x=f[top[x]];
    	}
    	if(dep[x]<dep[y])
    		swap(x,y);
    	T.change(1,1,n,id[y],id[x],z);
    }
    inline int qRange(int x,int y){
    	int res=0;
    	while(top[x]!=top[y]){
    		if(dep[top[x]]<dep[top[y]])
    			swap(x,y);
    		res+=T.ask(1,1,n,id[top[x]],id[x]);
    		res%=md;
    		x=f[top[x]];
    	}
    	if(dep[x]<dep[y])
    		swap(x,y);
    	res+=T.ask(1,1,n,id[y],id[x]);
    	res%=md;
    	return res;
    }
    inline void cTree(int x,int z){
    	T.change(1,1,n,id[x],id[x]+sz[x]-1,z);
    }
    inline int qTree(int x){
    	return T.ask(1,1,n,id[x],id[x]+sz[x]-1)%md;
    }
    int main(){
    	n=read();m=read();r=read();p=read();
    	F(i,1,n)
    		v[i]=read();
    	F(i,1,n-1){
    		int from=read(),to=read();
    		ins(from,to);ins(to,from);
    	}
    	dep[r]=1;
    	dfs1(r);
    	top[r]=r;
    	dfs2(r,r);
    	T.build_tree(1,1,n);
    	F(p,1,m){
    		int kd=read(),x,y,z;
    		if(kd==1)
    			x=read(),y=read(),z=read(),cRange(x,y,z);
        	if(kd==2)
    			x=read(),y=read(),printf("%d
    ",qRange(x,y));
    		if(kd==3)
    			x=read(),z=read(),cTree(x,z);
    		if(kd==4)
    			x=read(),printf("%d
    ",qTree(x));
    	}
    	return 0;
    }
    
  • 相关阅读:
    oracle 函数WMSYS.WM_CONCAT()的用法(行转列) 老猫
    PL/SQL 数独 九宫图 老猫
    oracle10g rman backup and recover 老猫
    Oracle SQL的优化 老猫
    Oracle数据库中的字符处理技巧总结 老猫
    WITH分析函数 老猫
    30套JSP网站源代码合集
    Java获取系统信息(cpu,内存,硬盘,进程等)的相关方法
    [原]Web Service学习
    常用Web Service汇总(天气预报、时刻表等)
  • 原文地址:https://www.cnblogs.com/hzf29721/p/10179341.html
Copyright © 2011-2022 走看看