1 条题解
-
0

#include <cstdio> #include <vector> using namespace std; const int M = 30005; const int N = 130; const int MOD = 10007; int read() { int x=0,f=1;char c; while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;} while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();} return x*f; } int n,m,q,a[M],inv[M];vector<int> g[M]; struct node { int x,y; node() {x=y=0;} void init(int a) {a?(x=a,y=0):(x=1,y=1);} friend node operator * (node A,int b) { b%=MOD; if(!b) A.y++;else A.x=A.x*b%MOD; return A; } friend node operator / (node A,int b) { b%=MOD; if(!b) A.y--;else A.x=A.x*inv[b]%MOD; return A; } int val() {return y?0:x;} }; void fwt(int *a,int n,int op) { for(int i=1;i<n;i<<=1) for(int j=0,t=i<<1;j<n;j+=t) for(int k=0;k<i;k++) { int fe=a[j+k],fo=a[i+j+k]; a[j+k]=(fe+fo)%MOD; a[i+j+k]=(fe-fo+MOD)%MOD; if(op==1) continue; a[j+k]=a[j+k]*inv[2]%MOD, a[i+j+k]=a[i+j+k]*inv[2]%MOD; } } int Ind,num[M],id[M],bot[M],t1[M],t2[M]; int siz[M],son[M],fa[M],top[M],e[N][N]; int f[M][N],h[M][N],lh[M][N];node lf[M][N]; void dfs1(int u,int p) { fa[u]=p;siz[u]=1; for(int v:g[u]) if(v^p) { dfs1(v,u); siz[u]+=siz[v]; if(siz[v]>siz[son[u]]) son[u]=v; } } void dfs2(int u,int tp) { top[u]=tp;num[u]=++Ind; bot[u]=num[u];id[Ind]=u; if(son[u]) dfs2(son[u],tp),bot[u]=bot[son[u]]; for(int v:g[u]) if(v^son[u] && v^fa[u]) dfs2(v,v); } void dfs3(int u) { for(int i=0;i<m;i++) f[u][i]=e[a[u]][i]; for(int v:g[u]) if(v!=fa[u]) { dfs3(v); for(int i=0;i<m;i++) { f[u][i]=(f[u][i]+f[u][i]*f[v][i])%MOD; h[u][i]=(h[u][i]+h[v][i])%MOD; } } for(int i=0;i<m;i++) h[u][i]=(h[u][i]+f[u][i])%MOD; } void dfs4() { for(int u=1;u<=n;u++) { for(int i=0;i<m;i++) lf[u][i].init(e[0][i]),lh[u][i]=0; for(int v:g[u]) if(v^fa[u] && v^son[u]) for(int i=0;i<m;i++) { lf[u][i]=lf[u][i]*(f[v][i]+1); lh[u][i]=(lh[u][i]+h[v][i])%MOD; } } } struct tree{int a[N],b[N],c[N],d[N];}t[M<<2]; tree operator * (tree A,tree B) { tree C; for(int i=0;i<m;i++) C.a[i]=C.b[i]=C.c[i]=C.d[i]=0; for(int i=0;i<m;i++) { C.a[i]=A.a[i]*B.a[i]%MOD; C.b[i]=(A.b[i]+A.a[i]*B.b[i])%MOD; C.c[i]=(B.a[i]*A.c[i]+B.c[i])%MOD; C.d[i]=(B.b[i]*A.c[i]+A.d[i]+B.d[i])%MOD; } return C; } void upd(int i,int x) { for(int j=0;j<m;j++) { t[i].a[j]=t[i].b[j]=t[i].c[j]=t[i].d[j] =lf[x][j].val()*e[a[x]][j]%MOD; t[i].d[j]=(t[i].d[j]+lh[x][j])%MOD; } } void build(int i,int l,int r) { if(l==r) {upd(i,id[l]);return ;} int mid=(l+r)>>1; build(i<<1,l,mid); build(i<<1|1,mid+1,r); t[i]=t[i<<1|1]*t[i<<1]; } void fuck(int i,int l,int r,int p) { if(l==r) {upd(i,id[l]);return ;} int mid=(l+r)>>1; if(mid>=p) fuck(i<<1,l,mid,p); else fuck(i<<1|1,mid+1,r,p); t[i]=t[i<<1|1]*t[i<<1]; } tree ask(int i,int l,int r,int L,int R) { if(L<=l && r<=R) return t[i]; int mid=(l+r)>>1; if(L>mid) return ask(i<<1|1,mid+1,r,L,R); if(R<=mid) return ask(i<<1,l,mid,L,R); return ask(i<<1|1,mid+1,r,L,R) *ask(i<<1,l,mid,L,R); } void get(int x) { tree zz=ask(1,1,n,num[x],bot[x]); for(int i=0;i<m;i++) t1[i]=zz.c[i],t2[i]=zz.d[i]; } void walk(int x,int c) { a[x]=c; while(x) { int y=fa[top[x]];get(top[x]); if(y) for(int i=0;i<m;i++) { lf[y][i]=lf[y][i]/(t1[i]+1); lh[y][i]=(lh[y][i]-t2[i]+MOD)%MOD; } fuck(1,1,n,num[x]);get(top[x]); if(y) for(int i=0;i<m;i++) { lf[y][i]=lf[y][i]*(t1[i]+1); lh[y][i]=(lh[y][i]+t2[i])%MOD; } x=y; } } signed main() { n=read();m=read();inv[0]=inv[1]=1; for(int i=1;i<=n;i++) a[i]=read(); for(int i=2;i<=n;i++) inv[i]=inv[MOD%i]*(MOD-MOD/i)%MOD; for(int i=1;i<n;i++) { int u=read(),v=read(); g[u].push_back(v); g[v].push_back(u); } for(int i=0;i<m;i++) e[i][i]=1,fwt(e[i],m,1); dfs1(1,0);dfs2(1,1);dfs3(1);dfs4(); build(1,1,n);char s[10]={};q=read(); while(q--) { scanf("%s",s+1); if(s[1]=='C') { int x=read(),y=read(); walk(x,y);a[x]=y; } else { get(1);fwt(t2,m,-1);int x=read(); printf("%d\n",t2[x]); } } }
- 1
信息
- ID
- 6580
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者