可以看immortalCO大佬的博客
我是参考了Manchery的代码…
#include
#include
#include
#include
using namespace std;
const int N=30010,M=310,P=10007,inv2=P+1>>1;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void rea(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
int n,k,q;
int v[N];
int e[M][M],inv[P+5];
struct U{
int x,y;
U(int a=0){
if(a) x=a,y=0;
else y=1,x=1;
}
friend U operator *(U a,int b){
if(!b) a.y++; else a.x=a.x*b%P;
return a;
}
friend U operator /(U a,int b){
if(!b) a.y--; else a.x=a.x*inv[b]%P;
return a;
}
int val(){
return y?0:x;
}
};
U a[N][M];
inline void FWT(int *a,int n,int r){
for(int i=1;i1)
for(int j=0;j1)
for(int k=0;kint x=a[j+k],y=a[j+k+i];
if(r) a[j+k]=(x+y)%P,a[j+k+i]=(x+P-y)%P;
else a[j+k]=(x+y)*inv2%P,a[j+k+i]=(x+P-y)*inv2%P;
}
}
inline void Pre(int t){
for(int i=0;i1; FWT(e[i],t,1);
}
inv[1]=1;
for(int i=2;i*inv[P%i]%P;
}
int cnt,G[N],fa[N],top[N],dpt[N],size[N],son[N];
struct edge{
int t,nx;
}E[N<<1];
inline void Insert(int x,int y){
E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt;
E[++cnt].t=x; E[cnt].nx=G[y]; G[y]=cnt;
}
void dfs1(int x,int f){
fa[x]=f; dpt[x]=dpt[f]+1; size[x]=1;
for(int i=G[x];i;i=E[i].nx)
if(E[i].t!=f){
dfs1(E[i].t,x);
if(size[E[i].t]>size[son[x]]) son[x]=E[i].t;
size[x]+=size[E[i].t];
}
}
vector<int> p[N];
int Q[N];
void dfs2(int x,int t){
top[x]=t; p[t].push_back(x);
if(x==t) Q[++*Q]=x;
if(son[x]) dfs2(son[x],t);
for(int i=G[x];i;i=E[i].nx)
if(E[i].t!=fa[x] && son[x]!=E[i].t) dfs2(E[i].t,E[i].t);
}
inline int cmp(const int &a,const int &b){
return dpt[a]>dpt[b];
}
int icnt,rt[N],ps[N];
int ls[N*3],rs[N*3],ft[N*3],val[N*3][M],lv[N*3][M],rv[N*3][M],pro[N*3][M];
inline void Up(int g){
for(int i=0;i*lv[rs[g]][i])%P;
lv[g][i]=(lv[ls[g]][i]+pro[ls[g]][i]*lv[rs[g]][i])%P;
rv[g][i]=(rv[rs[g]][i]+pro[rs[g]][i]*rv[ls[g]][i])%P;
pro[g][i]=pro[ls[g]][i]*pro[rs[g]][i]%P;
}
}
void Build(int &g,int l,int r,int x){
g=++icnt;
if(l==r){
for(int i=0;ix][l-1]][i].val();
ps[p[x][l-1]]=g;
return ;
}
int mid=l+r>>1;
Build(ls[g],l,mid,x); Build(rs[g],mid+1,r,x);
Up(g); ft[ls[g]]=ft[rs[g]]=g;
}
int ans[M];
inline void Modify(int x){
int cur=ps[x],y=top[x];
if(fa[y]){
for(int i=0;iy]][i]=a[fa[y]][i]/((lv[rt[y]][i]+e[0][i])%P);
}
for(int i=0;iy]][i])%P;
for(int i=0;ix][i].val();
cur=ft[cur];
while(cur) Up(cur),cur=ft[cur];
if(fa[y]){
for(int i=0;iy]][i]=a[fa[y]][i]*((lv[rt[y]][i]+e[0][i])%P);
}
for(int i=0;iy]][i])%P;
}
int tmp[M];
int main(){
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
rea(n); rea(k);
int t=1; while(t1; k=t;
Pre(k);
for(int i=1;i<=n;i++){
rea(v[i]);
for(int j=0;jfor(int i=1,x,y;ix),rea(y),Insert(x,y);
dfs1(1,0); dfs2(1,1);
sort(Q+1,Q+1+*Q,cmp);
for(int i=1;i<=*Q;i++){
int x=Q[i];
Build(rt[x],1,p[x].size(),x);
//FWT(val[rt[x]],k,0); for(int j=0;jprintf("%d ",val[rt[x]][j]); putchar('\n');
for(int j=0;jx]][j])%P;
if(fa[x]){
for(int j=0;jx]][j]=a[fa[x]][j]*((lv[rt[x]][j]+e[0][j])%P);
}
}
//FWT(ans,k,0); for(int i=0;iprintf("%d ",ans[i]); putchar('\n');
rea(q);
while(q--){
char opt; while((opt=nc())!='Q' && opt!='C');
if(opt=='C'){
int x,y; rea(x); rea(y);
for(int i=0;ix][i]=a[x][i]/e[v[x]][i];
v[x]=y;
for(int i=0;ix][i]=a[x][i]*e[v[x]][i];
while(x)
Modify(x),x=fa[top[x]];
}
else{
int x; rea(x);
for(int i=0;i0);
printf("%d\n",tmp[x]);
}
}
return 0;
}