题目:树上累加
#include <bits/stdc++.h>
#define N 101010
#define lson i<<1
#define rson i<<1|1
using namespace std;
const int mod=23333;
struct pp
{
int x[2],lazy;
int l,r;
}a[N<<3];//线段树
vector<int> v[N];//边
int w[N];//初始权重
int fa[N];//父节点
int has[N];//对应位置
int dfl[N],dfr[N],k;//对应子树的左端和右端
void dfs(int x)
{
int i,n=v[x].size();
int y;
dfl[x]=++k;
has[k]=x;
for(i=0;i<n;i++)
{
y=v[x][i];
if(fa[x]==y) continue;
fa[y]=x;
dfs(y);
}
dfr[x]=k;//
}
void add(int i,int x)//增加对应点权值
{
int len=(a[i].r-a[i].l+1)%mod;
a[i].lazy=(a[i].lazy+x)%mod;
a[i].x[0]=(a[i].x[0]+2*a[i].x[1]*x+((len*x)%mod)*x%mod)%mod;
a[i].x[1]=(a[i].x[1]+len*x)%mod;
}
void pushdown(int i)//向下更新
{
if(a[i].lazy)
{
add(lson,a[i].lazy);
add(rson,a[i].lazy);
a[i].lazy=0;
}
}
void pushup(int i)//向上更新
{
a[i].x[0]=(a[lson].x[0]+a[rson].x[0])%mod;
a[i].x[1]=(a[lson].x[1]+a[rson].x[1])%mod;
}
void build(int i,int l,int r)//建线段树
{
a[i].l=l;
a[i].r=r;
if(l==r)
{
a[i].x[0]=w[has[l]]*w[has[l]]%mod;
a[i].x[1]=w[has[l]];
return ;
}
int mid=(l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(i);
}
void updata(int i,int l,int r,int x)//更新
{
if(l<=a[i].l&&a[i].r<=r)
{
add(i,x);
return ;
}
if(r<a[i].l||a[i].r<l) return ;
pushdown(i);
updata(lson,l,r,x);
updata(rson,l,r,x);
pushup(i);
}
int qu(int i,int l,int r)//访问
{
if(l<=a[i].l&&a[i].r<=r)return a[i].x[0];
if(r<a[i].l||a[i].r<l) return 0;
pushdown(i);
return (qu(lson,l,r)+qu(rson,l,r))%mod;
}
int main()
{
//freopen("in.txt","r",stdin);
int i,n,q,s,t;
scanf("%d%d",&n,&q);
for(i=1;i<=n;i++)
{
scanf("%d",w+i);
w[i]%=mod;
}
for(i=1;i<n;i++)//存图
{
scanf("%d%d",&s,&t);
v[s].push_back(t);
v[t].push_back(s);
}
dfs(1);//得dfs序
build(1,1,n);//建线段树
while(q--)
{
int x,y,z;
scanf("%d",&z);
if(z==1)
{
scanf("%d%d",&x,&y);
updata(1,dfl[x],dfr[x],y%mod);
}else
{
scanf("%d",&x);
printf("%d\n",qu(1,dfl[x],dfr[x]));
}
}
return 0;
}