列表

详情


NC19428. 树上求和

描述

给你一棵根为1的有N个节点的树,以及Q次操作。
每次操作诸如:
1 x y:将节点x所在的子树的所有节点的权值加上y
2 x:询问x所在子树的所有节点的权值的平方和,答案模23333后输出

输入描述

第一行两个整数N,Q
第二行N个整数,第i个表示节点i的初始权值
接下来N-1行每行两个整数u,v,表示u和v之间存在一条树边
接下来Q行每行一个操作,格式如题目描述

输出描述

对于每个询问操作,输出一行一个整数,表示答案在模23333后的结果

示例1

输入:

5 5
0 0 0 0 0
1 2
1 3
3 4
3 5
1 1 3
1 3 7
1 4 5
1 5 6
2 1

输出:

599

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 141ms, 内存消耗: 8368K, 提交时间: 2020-07-16 19:24:40

#include<bits/stdc++.h>
using namespace std;
long long a[100005];
int n,q,u,v;
vector<int> g[100005];
int fa[100005];//记录父节点,0为没有父节点
bool vis[100005];//懒标记
long long add[100005];
const int mod=23333;
typedef long long ll;
void dfs(int x,int f){
  for(auto &i:g[x]){
    if(i==f)continue;
    fa[i]=x;
    dfs(i,x);
  }
}
void updown(int x){
  if(fa[x])updown(fa[x]);
  if(vis[x]){
    for(int i: g[x]){
        if(fa[x]==i)continue;//?
        a[i]+=add[x];
        vis[i]=1;
        add[i]+=add[x];
    } vis[x]=0;add[x]=0;
  }

}
ll qu(ll  x,ll  y){
    long long ans=0;
    if(vis[y]){
        vis[y]=0;
        for(auto i: g[y]){
            if(fa[y]==i)continue;
            add[i]+=add[y];
            a[i]+=add[y];
            vis[i]=1;
        }add[y]=0;
    }
    ans=(a[x]*a[x])%mod;
    for(auto i:g[x]){
            if(i==fa[x])continue;
        ans=(qu(i,x)+ans)%mod;
    }
    return ans;
}
int main(){
  std::ios::sync_with_stdio(0);
   cin>>n>>q;
   for(int i=1;i<=n;i++){
    cin>>a[i];
   }
    for(int i=1;i<n;i++){
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1,0);
    long long  z,x,y;
    while(q--){
           cin>>z;
    if(z==1){
        cin>>x>>y;
        a[x]+=y;
        vis[x]=1;
        add[x]+=y;
    }else{
    cin>>x;
    updown(x);
    cout<<qu(x,fa[x])<<endl;
    }
    }
}

C++11(clang++ 3.9) 解法, 执行用时: 277ms, 内存消耗: 9800K, 提交时间: 2020-07-22 17:23:41

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+3;
const int mod=23333;
vector<int>g[N];
int a[N],f[N]; 
void dfs(int s,int fa)
{
	for(auto v : g[s])
	{
		if(v!=fa)
		{
			f[v]=s;
			dfs(v,s);
		}
	}
	return ;
}
void dfs1(int s,int fa,int num)
{
	for(auto v:g[s])
	{
		if(v!=fa)
		{
			dfs1(v,s,num);
			a[v]=(a[v]+num)%mod;
		}
	}
	return;
}
int dfs2(int s,int fa)
{
	int ans=0;
	for(auto v:g[s])
	{
		if(v!=fa)
		{
			int num=dfs2(v,s);
			ans=(ans+num)%mod;
		}
	}
	return (ans+(1ll)*a[s]*a[s])%mod;
}
int main()
{
	int n,q;
	cin>>n>>q;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	f[1]=-1;
	dfs(1,-1);
	for(int i=0;i<q;i++)
	{
		int k,x,y;
		cin>>k;
		if(k==1)
		{
			cin>>x>>y;
			dfs1(x,f[x],y);
			a[x]=(a[x]+y)%mod;
		}
		else
		{
			cin>>x;
			cout<<dfs2(x,f[x])<<endl;
		}
	}
	return 0;
}

上一题