题解:P7826 「RdOI R3」RBT
螳臂题面,“什么都不做”指颜色也不染。但开头就直接说染成蓝色。
补充之前题解的内容。
题目上的“出现次数为奇数”和
发现操作
注意预处理
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5,mod=998244353;
int n,q,P,k,a[N],w[N],f[N];
inline int pw(int x,int y){
int ans=1;
for(;y;y>>=1,x=1ll*x*x%mod) if(y&1) ans=1ll*ans*x%mod;
return ans;
}
set<int> S[N];
int dfn[N],low[N],idx,xl[N];
void dfs(int p,int fa){
if(f[p]=fa) S[p].erase(fa);
xl[dfn[p]=++idx]=p;
for(int v:S[p]) dfs(v,p);
low[p]=idx;
}
bitset<500> base;
struct Tree{
int tag;
bitset<500> S;
}t[1<<18];
#define mid ((l+r)>>1)
void build(int p,int l,int r){
if(l==r){
t[p].S[a[xl[l]]]=1;
return;
}
build(2*p,l,mid),build(2*p+1,mid+1,r);
t[p].S=t[2*p].S^t[2*p+1].S;
}
inline void ins(int p,int v){
(t[p].tag+=v)%=P;
t[p].S=((t[p].S<<v)&base)|(t[p].S>>(P-v));
}
inline void pushdown(int p){
if(t[p].tag){
ins(2*p,t[p].tag);
ins(2*p+1,t[p].tag);
t[p].tag=0;
}
}
void change(int p,int l,int r,int lt,int rt,int v){
if(lt<=l&&r<=rt) return ins(p,v),void();
pushdown(p);
if(lt<=mid) change(2*p,l,mid,lt,rt,v);
if(mid<rt) change(2*p+1,mid+1,r,lt,rt,v);
t[p].S=t[2*p].S^t[2*p+1].S;
}
void change(int p,int l,int r,int x,int v){
if(l==r){
t[p].S.reset();
t[p].S[v]=1;
return;
}
pushdown(p);
if(x<=mid) change(2*p,l,mid,x,v);
else change(2*p+1,mid+1,r,x,v);
t[p].S=t[2*p].S^t[2*p+1].S;
}
bitset<500> query(int p,int l,int r,int lt,int rt){
if(lt<=l&&r<=rt) return t[p].S;
pushdown(p);
if(lt<=mid&&mid<rt) return query(2*p,l,mid,lt,rt)^query(2*p+1,mid+1,r,lt,rt);
return lt<=mid?query(2*p,l,mid,lt,rt):query(2*p+1,mid+1,r,lt,rt);
}
int main(){
read(n),read(q),read(P),read(k);
for(int i=0;i<P;++i) w[i]=pw(i,k);
for(int i=0;i<P;++i) base[i]=1;
for(int i=1;i<=n;++i) read(a[i]);
for(int i=1;i<n;++i){
int x,y;
read(x),read(y);
S[x].insert(y);
S[y].insert(x);
}
dfs(1,0);
build(1,1,n);
while(q--){
int op,x;
read(op),read(x);
if(op==1){
int v;read(v);
change(1,1,n,dfn[x],low[x],v);
}
if(op==2){
int v;read(v);
change(1,1,n,dfn[x],v);
}
if(op==3){
if(x==1) continue;
auto it=S[f[x]].find(x);
if(it!=S[f[x]].begin()) low[*(--it)]=low[x],S[f[x]].erase(x);
}
if(op==4){
auto s=query(1,1,n,dfn[x],low[x]);
long long ans=0;
for(int i=0;i<P;++i) if(s[i]) ans+=w[i];
print(ans%mod),pc('\n');
}
}
flush();
return 0;
}