zoukankan      html  css  js  c++  java
  • 洛谷 P3178 [HAOI2015]树上操作(树剖+线段树)

    传送门


    解题思路

    好板子啊。
    要不是是个省选题
    我才不写博客呢。

    树剖完了,就是单点修改+区间修改+区间求和。
    线段树维护即可。

    AC代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int maxn=100005;
    long long d[maxn*4],lazy[maxn*4];
    int n,m,p[maxn],cnt,siz[maxn],fa[maxn],son[maxn],id[maxn],tp[maxn],a[maxn],dfn[maxn],times;
    struct node{
    	int v,next;
    }e[maxn*2];
    void insert(int u,int v){
    	cnt++;
    	e[cnt].v=v;
    	e[cnt].next=p[u];
    	p[u]=cnt;
    }
    void dfs1(int u,int f){
    	siz[u]=1;
    	fa[u]=f;
    	for(int i=p[u];i!=-1;i=e[i].next){
    		int v=e[i].v;
    		if(v==f) continue;
    		dfs1(v,u);
    		siz[u]+=siz[v];
    		if(siz[v]>siz[son[u]]) son[u]=v;
    	}
    }
    void dfs2(int u,int top){
    	dfn[u]=++times;
    	id[times]=u;
    	tp[u]=top;
    	if(son[u]) dfs2(son[u],top);
    	for(int i=p[u];i!=-1;i=e[i].next){
    		int v=e[i].v;
    		if(v==son[u]||v==fa[u]) continue;
    		dfs2(v,v);
    	}
    }
    void pushdown(int id,int l,int r){
    	if(lazy[id]){
    		int mid=(l+r)/2;
    		lazy[id*2]+=lazy[id];
    		lazy[id*2+1]+=lazy[id];
    		d[id*2]+=1ll*(mid-l+1)*lazy[id];
    		d[id*2+1]+=1ll*(r-mid)*lazy[id];
    		lazy[id]=0;
    	}
    }
    void pushup(int id){
    	d[id]=d[id*2]+d[id*2+1];
    }
    void update(int id,int l,int r,int x,int y,long long v){
    	if(x>y) return;
    	if(x<=l&&r<=y){
    		d[id]+=v*(r-l+1);
    		lazy[id]+=v;
    		return;
    	}
    	int mid=(l+r)/2;
    	pushdown(id,l,r);
    	if(x<=mid) update(id*2,l,mid,x,y,v);
    	if(y>mid) update(id*2+1,mid+1,r,x,y,v);
    	pushup(id);
    }
    long long query(int id,int l,int r,int x,int y){
    	if(x>y) return 0;
    	if(x<=l&&r<=y){
    		return d[id];
    	}
    	pushdown(id,l,r);
    	int mid=(l+r)/2;
    	long long res=0;
    	if(x<=mid) res+=query(id*2,l,mid,x,y);
    	if(y>mid) res+=query(id*2+1,mid+1,r,x,y);
    	return res;
    }
    int main(){
    	ios::sync_with_stdio(false);
    	memset(p,-1,sizeof(p));
    	cin>>n>>m;
    	for(int i=1;i<=n;i++) cin>>a[i];
    	for(int i=1;i<n;i++){
    		int u,v;
    		cin>>u>>v;
    		insert(u,v);
    		insert(v,u);
    	}
    	dfs1(1,0);
    	dfs2(1,1);
    	for(int i=1;i<=n;i++) update(1,1,n,dfn[i],dfn[i],a[i]);
    	for(int i=1;i<=m;i++){
    		int op;
    		cin>>op;
    		if(op==1){
    			int u,x;
    			cin>>u>>x;
    			update(1,1,n,dfn[u],dfn[u],x);
    			continue;
    		}
    		if(op==2){
    			int u,x;
    			cin>>u>>x;
    			update(1,1,n,dfn[u],dfn[u]+siz[u]-1,x);
    			continue;
    		}
    		if(op==3){
    			int x;
    			long long ans=0;
    			cin>>x;
    			while(x!=0){
    				ans+=query(1,1,n,dfn[tp[x]],dfn[x]);
    				x=fa[tp[x]];
    			}
    			cout<<ans<<endl;
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    简化单例模式
    static
    单例模式之懒汉模式
    Car race game
    poj-2403
    poj-2612
    poj-1833
    poj--2782
    poj--2608
    poj--3086
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/15366498.html
Copyright © 2011-2022 走看看