zoukankan      html  css  js  c++  java
  • 洛谷P3178[HAOI2015]树上操作

    题目描述

    有一棵点数为 (N) 的树,以点 (1) 为根,且树点有边权。然后有(M) 个操作,分为三种:
    操作 (1) :把某个节点 (x) 的点权增加 (a)
    操作 (2) :把某个节点 (x) 为根的子树中所有点的点权都增加 (a)
    操作 (3) :询问某个节点 (x) 到根的路径中所有点的点权和。

    输入输出格式

    输入格式:

    第一行包含两个整数 (N), (M) 。表示点数和操作数。
    接下来一行 (N) 个整数,表示树中节点的初始权值。
    接下来 (N-1) 行每行两个正整数 (from), (to) , 表示该树中存在一条边 ((from), (to)) 。
    再接下来 (M) 行,每行分别表示一次操作。其中第一个数表示该操作的种类( (1-3) ) ,之后接这个操作的参数( (x) 或者 (x) (a) ) 。

    输出格式:

    对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

    输入输出样例

    输入样例#1:

    5 5
    1 2 3 4 5
    1 2
    1 4
    2 3
    2 5
    3 3
    1 2 1
    3 5
    2 1 2
    3 3
    

    输出样例#1:

    6
    9
    13
    

    说明

    对于 (100\%) 的数据, (N,M leq 100000),且所有输入数据的绝对值都不会超过 (10^6)

    思路:这道题跟洛谷(P3384)的唯一区别在于这里是单点修改,上面说过,区间修改包括单点修改,所以,可是说是一点区别都没有,就是打一遍加深一下对树剖的印象。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cctype>
    #define maxn 100007 
    #define ll long long 
    #define ls rt<<1
    #define rs rt<<1|1
    using namespace std;
    int head[maxn],d[maxn],a[maxn];
    int num,cnt,n,m,fa[maxn],id[maxn];
    int w[maxn],top[maxn],size[maxn],son[maxn];
    ll lazy[maxn<<2],sum[maxn<<2],y;
    inline ll qread() {
    	char c=getchar();ll num=0,f=1;
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    	for(;isdigit(c);c=getchar()) num=num*10+c-'0';
    	return num*f;
    }
    struct node {
    	int v,nxt;
    }e[maxn<<1];
    inline void ct(int u, int v) {
    	e[++num].v=v;
    	e[num].nxt=head[u];
    	head[u]=num;
    }
    inline void pushup(int rt) {
    	sum[rt]=sum[ls]+sum[rs];
    }
    void build(int rt, int l, int r) {
    	if(l==r) {
    		sum[rt]=a[l];
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(ls,l,mid);
    	build(rs,mid+1,r);
    	pushup(rt);
    }
    inline void pushdown(int rt, int len) {
    	if(lazy[rt]) {
    		lazy[ls]+=lazy[rt];
    		lazy[rs]+=lazy[rt];
    		sum[ls]+=(len-(len>>1))*lazy[rt];
    		sum[rs]+=(len>>1)*lazy[rt];
    		lazy[rt]=0;
    	}
    }
    void modify(int rt, int l, int r, int L, int R, ll val) {
    	if(L>r||R<l) return;
    	if(L<=l&&r<=R) {
    		sum[rt]+=val*(r-l+1);
    		lazy[rt]+=val;
    		return;
    	}
    	int mid=(l+r)>>1;
    	pushdown(rt,r-l+1);
    	modify(ls,l,mid,L,R,val),modify(rs,mid+1,r,L,R,val);
    	pushup(rt);
    }
    ll csum(int rt, int l, int r, int L, int R) {
    	if(L>r||R<l) return 0;
    	if(L<=l&&r<=R) return sum[rt];
    	int mid=(l+r)>>1;
    	pushdown(rt,r-l+1);
    	return csum(ls,l,mid,L,R)+csum(rs,mid+1,r,L,R);
    }
    void dfs1(int u, int f) {
    	size[u]=1;
    	for(int i=head[u];i;i=e[i].nxt) {
    		int v=e[i].v;
    		if(v!=f) {
    			d[v]=d[u]+1;
    			fa[v]=u;
    			dfs1(v,u);
    			size[u]+=size[v];
    			if(size[v]>size[son[u]]) son[u]=v;
    		}
    	}
    }
    void dfs2(int u, int t) {
    	id[u]=++cnt;
    	a[cnt]=w[u];
    	top[u]=t;
    	if(son[u]) dfs2(son[u],t);
    	for(int i=head[u];i;i=e[i].nxt) {
    		int v=e[i].v;
    		if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
    	}
    }
    ll calc(int x, int y) {
    	ll ans=0;
    	int fx=top[x],fy=top[y];
    	while(fx!=fy) {
    		if(d[fx]<d[fy]) swap(x,y),swap(fx,fy);
    		ans+=csum(1,1,cnt,id[fx],id[x]);
    		x=fa[fx],fx=top[x];
    	}
    	if(id[x]>id[y]) swap(x,y);
    	ans+=csum(1,1,cnt,id[x],id[y]);
    	return ans;
    }
    int main() {
    	n=qread(),m=qread();
    	for(int i=1;i<=n;++i) w[i]=qread();
    	for(int i=1,u,v;i<n;++i) {
    		u=qread(),v=qread();
    		ct(u,v);ct(v,u);
    	}
    	d[1]=1,fa[1]=1;
    	dfs1(1,0);dfs2(1,1);build(1,1,n);
    	for(int i=1,k,x;i<=m;++i) {
    		k=qread();
    		if(k==1) {
    			x=qread(),y=qread();
    			modify(1,1,n,id[x],id[x],y);
    		}
    		if(k==2) {
    			x=qread(),y=qread();
    			modify(1,1,n,id[x],id[x]+size[x]-1,y);
    		}
    		if(k==3) {
    			x=qread();
    			printf("%lld
    ",calc(1,x));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Git fetch和git pull的区别
    git revert和git reset的区别
    JSF 与 HTML 标签的联系
    3. Decorator
    2. Observer
    1. Strategy
    继承构造函数的执行顺序
    模板特化
    8.1.2 Template instantiation (Accelerated C++)
    std::cin
  • 原文地址:https://www.cnblogs.com/grcyh/p/10201363.html
Copyright © 2011-2022 走看看