zoukankan      html  css  js  c++  java
  • 模板

    注意事项:

    • 需要的数组:1.建图(ver,nex,head).  2,维护链的数据结构:线段树/树状数组.  3.树剖:dfn,wson,top,size,deep

    • dfn[1]=fa[1]=1;
    • gai(dfn[x])
    • dfs1记录字数大小size/深度d/父节点fa/重儿子wson
    • dfs1记录dfn,pre,链顶top
    #include<iostream>
    #include<stdio.h>
    
    using namespace std;
    
    int g,q,h,i,m,n,j,k,a[100001],nex[100001],head[100001],ver[100001],cnt;
    int wson[100005],top[100005],dfn[100001],d[100001],fa[100001],size[100001];
    int pre[100005],sum[400010],smm[400011];
    char c[10001];
    
    void add(int x,int y)
    {
    	cnt+=1;
    	ver[cnt]=y;
    	nex[cnt]=head[x];
    	head[x]=cnt;
    }
    
    void update(int now)
    {
    	sum[now]=sum[now*2]+sum[now*2+1];
    	smm[now]=max(smm[now*2],smm[now*2+1]);
    }
    
    void built(int now,int l,int r)
    {
    	if(l==r) sum[now]=smm[now]=a[pre[l]];
    	else
    	{
    		int mid=(l+r)/2;
    		built(now*2,l,mid);
    		built(now*2+1,mid+1,r);
    		update(now);
    	}
    }
    
    void dfs1(int x,int y)
    {
    	size[x]=1;
    	for(int i=head[x];i;i=nex[i])
    	{
    		int t=ver[i];
    		if(t==y) continue;
    		fa[t]=x;
    		d[t]=d[x]+1;
    		dfs1(t,x);
    		if(size[t]>size[wson[x]]) wson[x]=t;
    		size[x]+=size[t];
    	}
    }
    
    void dfs2(int x,int y)
    {
    	cnt+=1;
    	dfn[x]=cnt; pre[cnt]=x; top[x]=y;
    	if(wson[x]) dfs2(wson[x],y);
    	for(int i=head[x];i;i=nex[i])
    	{
    		int t=ver[i];
    		if(t==fa[x] || t==wson[x]) continue;
    		dfs2(t,t);
    	}
    }
    
    int qsum(int now,int l,int r,int ll,int rr)
    {
    	if((l>=ll)&&(r<=rr)) return sum[now];
    	int mid=(l+r)/2,ans=0;
    	if(ll<=mid) ans+=qsum(now*2,l,mid,ll,rr);
    	if(rr>mid) ans+=qsum(now*2+1,mid+1,r,ll,rr);
    	return ans;
    }
    
    int qmax(int now,int l,int r,int ll,int rr)
    {
    	if((l>=ll)&&(r<=rr)) return smm[now];
    	int mid=(l+r)/2,ans=-0x7ffffff;
    	if(ll<=mid) ans=max(ans,qmax(now*2,l,mid,ll,rr));
    	if(rr>mid) ans=max(ans,qmax(now*2+1,mid+1,r,ll,rr));
    	return ans;
    }
    
    void gai(int now,int l,int r,int w,int z)
    {
    	if(l==r) sum[now]=smm[now]=z;
    	else
    	{
    		int mid=(l+r)/2,ans=0;
    		if(mid>=w) gai(now*2,l,mid,w,z);
    		else gai(now*2+1,mid+1,r,w,z);
    		update(now);
    	}
    }
    
    int cham(int x,int y)
    {
    	int ans=-0x7fffffff;
    	while(top[x]!=top[y])
    	{
    		if(d[top[x]]<d[top[y]]) swap(x,y);
    		ans=max(qmax(1,1,n,dfn[top[x]],dfn[x]),ans);
    		x=fa[top[x]];
    	}
    	if(d[x]<d[y]) swap(x,y);
    	ans=max(ans,qmax(1,1,n,dfn[y],dfn[x]));
    	return ans;
    }
    
    int chas(int x,int y)
    {
    	int ans=0;
    	while(top[x]!=top[y])
    	{
    		if(d[top[x]]<d[top[y]]) swap(x,y);
    		ans+=qsum(1,1,n,dfn[top[x]],dfn[x]);
    		x=fa[top[x]];
    	}
    	if(d[x]<d[y]) swap(x,y);
    	ans+=qsum(1,1,n,dfn[y],dfn[x]);
    	return ans;
    }
    
    int main()
    {
    	scanf("%d",&n);
    	for(i=1;i<n;i++) 
    	{
    		scanf("%d%d",&g,&h);
    		add(g,h);
    		add(h,g);
    	}
    	for(i=1;i<=n;i++) scanf("%d",&a[i]);
    	scanf("%d",&q);
    	d[1]=fa[1]=1; cnt=0;
    	dfs1(1,0); dfs2(1,1); built(1,1,n);
    	
    	for(i=1;i<=q;i++)
    	{
    		scanf("%s%d%d",c,&g,&h);
    		if(c[1]=='H') gai(1,1,n,dfn[g],h);
    		if(c[1]=='M') printf("%d
    ",cham(g,h));
    		if(c[1]=='S') printf("%d
    ",chas(g,h));
    	}
    }
    

      

  • 相关阅读:
    删数问题
    八中公司_二分图带权最大匹配模板题
    完美子图(这道题太难了,得写下来要不回头又忘了)
    最近集训的图论(思路+实现)题目汇总(内容包含tarjan、分层图、拓扑、差分、奇怪的最短路):
    方格取数(简单版)+小烈送菜(不知道哪来的题)-----------奇怪的dp增加了!
    单调队列优化题:最大数(P1198)
    单调队列+线性dp题Watching Fireworks is Fun (CF372C)
    关于看了几道洛谷灰题(暂无评定)的感想
    洛谷的奇妙今日运势
    互不侵犯(洛谷P1896)
  • 原文地址:https://www.cnblogs.com/ZUTTER/p/9285725.html
Copyright © 2011-2022 走看看