zoukankan      html  css  js  c++  java
  • 【DFS序】【线段树】bzoj4034 [HAOI2015]T2

    分开维护树的入栈序和出栈序,用两棵线段树。回答时就是用一颗的减去另一棵的。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    #define N 100001
    ll sumv[2][N<<2],delta[2][N<<2];
    void pushdown(int o,int rt,int sz)
    {
    	if(delta[o][rt])
    	  {
    	  	delta[o][rt<<1]+=delta[o][rt];
    	  	delta[o][rt<<1|1]+=delta[o][rt];
    	  	sumv[o][rt<<1]+=delta[o][rt]*(ll)(sz-(sz>>1));
    	  	sumv[o][rt<<1|1]+=delta[o][rt]*(ll)(sz>>1);
    	  	delta[o][rt]=0;
    	  }
    }
    void Update(int o,int ql,int qr,int v,int rt,int l,int r)
    {
    	if(ql<=l&&r<=qr)
    	  {
    	  	delta[o][rt]+=(ll)v;
    	  	sumv[o][rt]+=(ll)v*(ll)(r-l+1);
    	  	return;
    	  }
    	int m=(l+r>>1);
    	pushdown(o,rt,r-l+1);
    	if(ql<=m) Update(o,ql,qr,v,rt<<1,l,m);
    	if(m<qr) Update(o,ql,qr,v,rt<<1|1,m+1,r);
    	sumv[o][rt]=sumv[o][rt<<1]+sumv[o][rt<<1|1];
    }
    ll Query(int o,int qr,int rt,int l,int r)
    {
    	if(r<=qr) return sumv[o][rt];
    	int m=(l+r>>1); ll res=0;
    	pushdown(o,rt,r-l+1);
    	res+=Query(o,qr,rt<<1,l,m);
    	if(m<qr) res+=Query(o,qr,rt<<1|1,m+1,r);
    	return res;
    }
    int n,m,a[N];
    int e,v[N<<1],first[N],next[N<<1];
    void AddEdge(int U,int V)
    {
    	v[++e]=V;
    	next[e]=first[U];
    	first[U]=e;
    }
    int Ls[N],Rs[N],oLs[N],oRs[N],xu[N<<1];
    int tot,to2,to3;
    void dfs(int U,int Fa)
    {
    	Ls[U]=++tot;
    	xu[++to3]=U;
    	for(int i=first[U];i;i=next[i])
    	  if(v[i]!=Fa)
    	    dfs(v[i],U);
    	Rs[U]=tot;
    	xu[++to3]=U;
    	oRs[U]=oLs[U]=++to2;
    }
    void df2(int U,int Fa)
    {
    	for(int i=first[U];i;i=next[i])
    	  if(v[i]!=Fa)
    	    {
    	      df2(v[i],U);
    	      oLs[U]=min(oLs[U],oLs[v[i]]);
    	    }
    }
    bool hav[N];
    int Map[N];
    int main()
    {
    	int x,y,op;
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i)
    	  scanf("%d",&a[i]);
    	for(int i=1;i<n;++i)
    	  {
    	  	scanf("%d%d",&x,&y);
    	  	AddEdge(x,y);
    	  	AddEdge(y,x);
    	  }
    	dfs(1,0);
    	df2(1,0);
    	int last=0;
    	for(int i=1;i<=to3;++i)
    	  if(!hav[xu[i]])
    	  	{
    	  	  Map[xu[i]]=last;
    	  	  hav[xu[i]]=1;
    	  	}
    	  else
    	    last=xu[i];
    	for(int i=1;i<=n;++i)
    	  {
    	  	Update(0,Ls[i],Ls[i],a[i],1,1,n);
    	  	Update(1,oRs[i],oRs[i],a[i],1,1,n);
    	  }
    	for(;m;--m)
    	  {
    	  	scanf("%d%d",&op,&x);
    	  	if(op==1)
    	  	  {
    	  	  	scanf("%d",&y);
    	  	  	Update(0,Ls[x],Ls[x],y,1,1,n);
    	  		Update(1,oRs[x],oRs[x],y,1,1,n);
    	  	  }
    	  	else if(op==2)
    	  	  {
    	  	  	scanf("%d",&y);
    	  	  	Update(0,Ls[x],Rs[x],y,1,1,n);
    	  		Update(1,oLs[x],oRs[x],y,1,1,n);
    	  	  }
    	  	else
    	  	  printf("%I64d
    ",Query(0,Ls[x],1,1,n)-((!Map[x])?0:Query(1,oRs[Map[x]],1,1,n)));
    	  }
    	return 0;
    }
  • 相关阅读:
    Android Bitmap 常见的几个操作:缩放,裁剪,旋转,偏移
    vue.js 本地解决跨域
    VUE添加网站favicon.ico图标
    在mpvue引入flyio
    页面中加入地图map
    360校招——最后赢家(C++)
    奇安信校招——买口罩(c++)
    携程校招——携程海洋馆的海豚小宝宝(C++)
    阿里云Web应用托管服务,低成本建个人博客(wordpress和wiki.js)
    (嵌入式)工程模板的创建和MDK下配置开发STM32F103ZE
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4505158.html
Copyright © 2011-2022 走看看