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

      

  • 相关阅读:
    接下来是沉重的一堆任务啊!
    wxPython入门(一)
    一个比较好玩的东西——硬链接
    Python打印本机IP
    voddown.py v0.3 基本上就这样吧
    Python的正则表达式
    【转】Python命名习惯
    bat命令
    试用了GIMP的Smart remove selection,结果有些失望啊,哈哈
    STM32学习笔记(1)——搭建库函数工程
  • 原文地址:https://www.cnblogs.com/ZUTTER/p/9285725.html
Copyright © 2011-2022 走看看