首页 > 其他分享 >P3178 [HAOI2015]树上操作 的dfs序题解

P3178 [HAOI2015]树上操作 的dfs序题解

时间:2022-11-22 10:14:49浏览次数:50  
标签:P3178 ch int 题解 点权 dfs 操作 节点

操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

//点修改+树修改,(点->根)链查询
#include<bits/stdc++.h>
#define ll long long
#define rint register int
using namespace std;
const int N=1e6+5;
int n,m,root,cnt,tim;
int h[N],be[N],en[N],dep[N];
ll d[N],s1[N],s2[N],size[N],s[N];
struct edge
{
    int v,nxt;
} e[N<<1];
inline ll read()
{
    ll x=0;
    bool flag=false;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')    flag=true;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<3)+(x<<1)+(ch^48);
        ch=getchar();
    }
    return flag?~x+1:x;
}
void add_edge(int u,int v)
{
    e[++cnt].v=v;
    e[cnt].nxt=h[u];
    h[u]=cnt;
}
void dfs(int u,int fat)
{
    dep[u]=dep[fat]+1;
    be[u]=++tim;
    size[u]+=d[u];//记录到根节点的距离 
    for(rint i=h[u];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if(v!=fat)
        {
            size[v]+=size[u];
            dfs(v,u);
        }
    }
    en[u]=tim;
}
void add(int x,ll c)
{
	if (x==0) return ;
	for (rint i=x;i<=n;i+=(i&(-i)))
	{
		s[i]+=c;
	}
}
void add1(int x,ll c)//处理s1 记录v的变化 
{
    if(x==0)    return;
    for(rint i=x;i<=n;i+=(i&(-i)))
        s1[i]+=c;
}
void add2(int x,ll c)//处理s2 记录dep的乘积 
{
    if(x==0)    return;
    for(rint i=x;i<=n;i+=(i&(-i)))
        s2[i]+=c;
}
ll sum(int x)
{
	ll ans=0;
	for(rint i=x;i;i-=(i&(-i)))
	{
		ans+=s[i];
	}
	return ans;
}
ll sum1(int x)//求v的和 
{
    ll ans=0;
    for(rint i=x;i;i-=(i&(-i)))
        ans+=s1[i];
    return ans;
}
ll sum2(int x)//求乘积的和 
{
    ll ans=0;
    for(rint i=x;i;i-=(i&(-i)))
        ans+=s2[i];
    return ans;
}
int main()
{
    n=read(),m=read(),root=1;
    for(rint i=1;i<=n;++i)
        d[i]=read();
    for(rint i=1;i<n;++i)
    {
        int x=read(),y=read();
        add_edge(x,y);
        add_edge(y,x);
    }
    dfs(root,0);
    for(rint i=1;i<=m;++i)
    {
        int op=read();//(deep[y]-deep[x]+1)*v=v*(deep[y]+1)-v*deep[x]
        if(op==1)
        {
            int x=read();ll w=read();
            add(be[x],w);add(en[x]+1,-w);//差分记录v 
        }
        if(op==2)
        {
            int x=read();ll w=read();
            add1(be[x],w);add1(en[x]+1,-w);//差分记录v 
            add2(be[x],dep[x]*w);add2(en[x]+1,-dep[x]*w);//差分记录dep*v 
        }
        if(op==3)
        {
            int a=read();
            ll ans=size[a];//先加上原数据 
            ans+=((dep[a]+1)*sum1(be[a])-sum2(be[a]));//子树修改求和 
            ans+=sum(be[a]);//点修改求和 
            printf("%lld\n",ans);
        }
    }
}
/*
in
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
out
6
9
13

*/

  

标签:P3178,ch,int,题解,点权,dfs,操作,节点
From: https://www.cnblogs.com/smghj/p/16914218.html

相关文章

  • 常见问题解决方案
    1.Failedtofindthek3s-selinuxpolicy检查master机器上是否已经安装了不同版本的k3s-selinux或者selinux-policy工具包,建议将机器上相关包全部卸载以后重新执行安装。......
  • 问题解决:Unlink of file '.git/objects/pack/****' failed. Should I try again?
    gitpull拉取代码的时候遇到上面的错误,选择是或者否都不行,貌似说文件被占用了,也尝试用过找到.git里面对应的文件删除掉,也可以解决,不过文件占用多了,不可能一个个手动清......
  • 搜索与图论篇——DFS和BFS
    搜索与图论篇——DFS和BFS本次我们介绍搜索与图论篇中DFS和BFS,我们会从下面几个角度来介绍:DFS和BFS简介DFS数字排序DFS皇后排序DFS树的重心BFS走迷宫BFS八数码BFS......
  • CF1601 题解
    偶然看这一场的题目,忽然很有感觉,于是写了一下A题面考虑每一位可以单独分开考虑考虑单独的一位,每次要选\(m\)个位置,可能产生贡献的位置就是这位为1的数,设数量为\(x......
  • 【题解】TEST 22.11.21 - 计数(感谢强大艾尔法!!1)
    我们要求的是:\[\begin{aligned}G(x)&=\sum_{i\geq0}(i+n-m)!(-1)^{m-i}x^i\\G'(x)&=\sum_{i\geq1}i(i+n-m)!(-1)^{m-i}x^{i-1}\end{aligned}\]考虑凑\(\sum\limits......
  • 11.21 模拟赛题解
    \(\textdistance\)简要题意给定一棵\(n\)个结点的无根树,每条边有一个边权,询问以哪一个点作为根时,到其他所有节点的距离之和最大。距离的定义为到该点最短路径上的边权......
  • DTOJ 2022-11-21 测试 题解
    测试成果非常寄35+56+0+8=99基本上把能犯的错误都犯了T1记得dp数组初始化\(-\infty\)!!!!T2记得认真暴搜,不要乱记录访问状态T3记得把调试删掉!!!!!T4记得开longlong......
  • AtCoder 题解集
    虽然暂时不知道会不会从XCPC中退役,但还是想把这个题解集给维护下去。\(created\;at\;2022/6/24\;by\;Roshin\)目录AGCARCABCABC138F.Coincidence(结论,数位DP)AB......
  • ZR2448 题解
    题意给定一个长度为\(n\)的匹配的括号序列\(s\)。给出\(q\)组询问,每组询问形如:光标从\(s\)的第\(a\)个字符出发,使用一下三种操作:将光标移到左边的字符。将光......
  • [题解] CF1149D Abandoning Roads
    难得自己想出来一道3000分的题,虽然说考试的时候打挂了...首先先对较小的边缩点,然后求连通块内的最短路。显然,连通块内其实想怎么走就怎么走,但不能走较大的边。然后不同......