考虑维护原树的lct,在上面dp,由于dp方程特殊,均为异或卷积或加法,计算中可以只使用fwt后的序列

v[w]表示联通子树的最浅点为w,且不选w的splay子树中的点

l[w]表示联通子树的最浅点在w的lct子树中,且选w的splay子树中极左点(w的splay子树为{w}+{u的splay子树,满足u==ch[w][0]||u==ch[w][1]})

r[w]表示联通子树的最浅点在w的lct子树中,且选w的splay子树中极右点

lr[w]表示联通子树的最浅点为w,且选w的splay子树中所有的点

s[w]表示联通子树的最浅点在w的lct子树中(w的lct子树为{w}+{u的lct子树,满足fa[u]==w})

ss[w]表示联通子树的最浅点在w的lct子树中,且不选w

时间复杂度O((n+q)mlogm),由于dp方程复杂以及lct自带的常数,总体常数较大

  1. #include<bits/stdc++.h>
  2. #define fm(i) for(int i=0;i<m;++i)
  3. typedef int arr[];
  4. const int N=,P=;
  5. int n,m,v0[N],ivs[],*iv=ivs+P+;
  6. arr x0[],ans,tmp;
  7. std::vector<int>e[N];
  8. struct node{
  9. node*c[],*f;
  10. arr v,vt,l,r,lr,s,ss;
  11. bool nrt();
  12. void up();
  13. void setrc(node*w);
  14. }ns[N],*nil=ns,*rt=ns+;
  15. void cpy(int*a,int*b){memcpy(a,b,sizeof(int)*m);}
  16. bool node::nrt(){return this==f->c[]||this==f->c[];}
  17. void node::up(){
  18. fm(i){
  19. int vi=vt[i]?:v[i];
  20. int vc0lr=vi*c[]->lr[i]%P;
  21. int vc0r=vi*c[]->r[i]%P;
  22. l[i]=(vc0lr*c[]->l[i]+c[]->l[i])%P;
  23. r[i]=(vc0r*c[]->lr[i]+c[]->r[i])%P;
  24. lr[i]=vc0lr*c[]->lr[i]%P;
  25. s[i]=(vc0r*c[]->l[i]+ss[i])%P;
  26. }
  27. }
  28. void mul(int*v1,int*t,int*v2){fm(i)v2[i]?v1[i]=v1[i]*v2[i]%P:++t[i];}
  29. void div(int*v1,int*t,int*v2){fm(i)v2[i]?v1[i]=v1[i]*iv[v2[i]]%P:--t[i];}
  30. void node::setrc(node*w){
  31. if(c[]!=nil)mul(v,vt,c[]->l);
  32. c[]=w;
  33. if(c[]!=nil)div(v,vt,c[]->l);
  34. up();
  35. }
  36. void rot(node*w){
  37. node*f=w->f,*g=f->f;
  38. int d=w==f->c[];
  39. if(f->nrt())g->c[g->c[]==f]=w;
  40. w->f=g;
  41. (f->c[d]=w->c[d^])->f=f;
  42. (w->c[d^]=f)->f=w;
  43. fm(i){
  44. int x=f->ss[i],y=f->c[d]->s[i];
  45. f->ss[i]=(x-w->s[i]+y)%P;
  46. w->s[i]=f->s[i];
  47. w->ss[i]-=y;
  48. }
  49. f->up();
  50. fm(i)w->ss[i]=(w->ss[i]+f->s[i])%P;
  51. }
  52. void sp(node*w){
  53. if(!w->nrt())return;
  54. do{
  55. node*f=w->f;
  56. if(f->nrt())rot((f->c[]==w)==(f->f->c[]==f)?f:w);
  57. rot(w);
  58. }while(w->nrt());
  59. w->up();
  60. }
  61. void acs(node*x){
  62. rt=x;
  63. for(node*y=nil;x!=nil;sp(x),x->setrc(y),y=x,x=x->f);
  64. sp(rt);
  65. }
  66. void dfs(int w,int pa){
  67. for(int i=;i<e[w].size();++i){
  68. int u=e[w][i];
  69. if(u!=pa){
  70. dfs(u,w);
  71. ns[u].f=ns+w;
  72. mul(ns[w].v,ns[w].vt,ns[u].l);
  73. fm(j)ns[w].ss[j]+=ns[u].s[j];
  74. }
  75. }
  76. ns[w].up();
  77. }
  78. void dwt(int*a){
  79. for(int i=;i<m;i<<=){
  80. for(int j=;j<m;j+=i<<){
  81. int*b=a+j,*c=b+i;
  82. for(int k=;k<i;++k){
  83. int x=b[k],y=c[k];
  84. b[k]=x+y;
  85. c[k]=x-y;
  86. }
  87. }
  88. }
  89. fm(i)a[i]%=P;
  90. }
  91. char buf[],*ptr=buf;
  92. int _(){
  93. int x=;
  94. while(*ptr<)++ptr;
  95. while(*ptr>)x=x*+*ptr++-;
  96. return x;
  97. }
  98. int main(){
  99. fread(buf,,sizeof(buf),stdin);
  100. n=_();m=_();
  101. for(int i=;i<m;++i){
  102. x0[i][i]=;
  103. dwt(x0[i]);
  104. }
  105. iv[-P]=iv[]=;
  106. for(int i=;i<P;++i)iv[i-P]=iv[i]=(P-P/i)*iv[P%i]%P;
  107. for(int i=;i<=n;++i)ns[i]=(node){nil,nil,nil};
  108. cpy(nil->l,x0[]);
  109. cpy(nil->r,x0[]);
  110. cpy(nil->lr,x0[]);
  111. for(int i=;i<=n;++i){
  112. v0[i]=_();
  113. cpy(ns[i].v,x0[v0[i]]);
  114. }
  115. for(int i=,a,b;i<n;++i){
  116. a=_(),b=_();
  117. e[a].push_back(b);
  118. e[b].push_back(a);
  119. }
  120. dfs(,);
  121. for(int q=_(),ed=;q;--q){
  122. if(_()==){
  123. if(ed){
  124. cpy(ans,rt->s);
  125. dwt(ans);
  126. ed=;
  127. }
  128. printf("%d\n",(ans[_()]*iv[m]%P+P)%P);
  129. }else{
  130. ed=;
  131. int w=_(),x=_();
  132. acs(ns+w);
  133. int*v1=x0[v0[w]],*v2=x0[x];
  134. fm(i)rt->v[i]=rt->v[i]*v1[i][iv]%P*v2[i]%P;
  135. fm(i)ans[i]=rt->vt[i]?:rt->v[i];
  136. dwt(ans);
  137. v0[w]=x;
  138. rt->up();
  139. }
  140. }
  141. return ;
  142. }

由于树形态不改变,也可以建一棵深度不超过logn+O(1)的静态lct,可以明显减小常数

  1. #include<bits/stdc++.h>
  2. #define fm(i) for(int i=0;i<m;++i)
  3. typedef int arr[];
  4. const int N=,P=;
  5. int n,m,v0[N],ivs[],*iv=ivs+P+;
  6. arr x0[],ans,tmp;
  7. std::vector<int>e[N];
  8. struct node{
  9. node*c[],*f;
  10. arr v,vt,l,r,lr,s,ss;
  11. bool isrt();
  12. void up();
  13. }ns[N],*nil=ns,*rt;
  14. bool node::isrt(){return this!=f->c[]&&this!=f->c[];}
  15. void cpy(int*a,int*b){memcpy(a,b,sizeof(int)*m);}
  16. void node::up(){
  17. fm(i){
  18. int vi=vt[i]?:v[i];
  19. int vc0lr=vi*c[]->lr[i]%P;
  20. int vc0r=vi*c[]->r[i]%P;
  21. l[i]=(vc0lr*c[]->l[i]+c[]->l[i])%P;
  22. r[i]=(vc0r*c[]->lr[i]+c[]->r[i])%P;
  23. lr[i]=vc0lr*c[]->lr[i]%P;
  24. s[i]=(vc0r*c[]->l[i]+ss[i])%P;
  25. }
  26. }
  27. void mul(int*v1,int*t,int*v2){fm(i)v2[i]?v1[i]=v1[i]*v2[i]%P:++t[i];}
  28. void div(int*v1,int*t,int*v2){fm(i)v2[i]?v1[i]=v1[i]*iv[v2[i]]%P:--t[i];}
  29. int fa[N],sz[N],son[N],dep[N],top[N],ws[N],wp;
  30. void f1(int w,int pa){
  31. dep[w]=dep[fa[w]=pa]+(sz[w]=);
  32. for(int i=;i<e[w].size();++i){
  33. int u=e[w][i];
  34. if(u!=pa){
  35. f1(u,w);
  36. sz[w]+=sz[u];
  37. if(sz[u]>sz[son[w]])son[w]=u;
  38. }
  39. }
  40. ns[w].up();
  41. }
  42. node*build(int L,int R,node*f){
  43. if(L>R)return nil;
  44. int L0=L,R0=R;
  45. for(int M,s0=ws[L][sz]+ws[R+][sz];L<R;ws[M=L+R+>>][sz]*<s0?R=M-:L=M);
  46. node*w=ns+ws[L];
  47. w->c[]=build(L0,L-,w);
  48. w->c[]=build(L+,R0,w);
  49. w->f=f;
  50. w->up();
  51. if(f!=nil){
  52. fm(i)f->ss[i]+=w->s[i];
  53. if(L0==&&R0==wp)mul(f->v,f->vt,w->l);
  54. }
  55. return w;
  56. }
  57. void f2(int w,int tp){
  58. top[w]=tp;
  59. for(int i=;i<e[w].size();++i){
  60. int u=e[w][i];
  61. if(u!=fa[w]&&u!=son[w])f2(u,u);
  62. }
  63. if(son[w])f2(son[w],tp);
  64. else{
  65. wp=;
  66. for(int a=tp;a;a=son[a])ws[++wp]=a;
  67. ws[wp+]=;
  68. rt=build(,wp,ns+fa[tp]);
  69. }
  70. }
  71. void dwt(int*a){
  72. for(int i=;i<m;i<<=){
  73. for(int j=;j<m;j+=i<<){
  74. int*b=a+j,*c=b+i;
  75. for(int k=;k<i;++k){
  76. int x=b[k],y=c[k];
  77. b[k]=x+y;
  78. c[k]=x-y;
  79. }
  80. }
  81. }
  82. fm(i)a[i]%=P;
  83. }
  84. char buf[],*ptr=buf;
  85. int _(){
  86. int x=;
  87. while(*ptr<)++ptr;
  88. while(*ptr>)x=x*+*ptr++-;
  89. return x;
  90. }
  91. int main(){
  92. fread(buf,,sizeof(buf),stdin);
  93. n=_();m=_();
  94. for(int i=;i<m;++i){
  95. x0[i][i]=;
  96. dwt(x0[i]);
  97. }
  98. iv[-P]=iv[]=;
  99. for(int i=;i<P;++i)iv[i-P]=iv[i]=(P-P/i)*iv[P%i]%P;
  100. for(int i=;i<=n;++i)ns[i]=(node){nil,nil,nil};
  101. cpy(nil->l,x0[]);
  102. cpy(nil->r,x0[]);
  103. cpy(nil->lr,x0[]);
  104. for(int i=;i<=n;++i){
  105. v0[i]=_();
  106. cpy(ns[i].v,x0[v0[i]]);
  107. }
  108. for(int i=,a,b;i<n;++i){
  109. a=_(),b=_();
  110. e[a].push_back(b);
  111. e[b].push_back(a);
  112. }
  113. f1(,);f2(,);
  114. for(int q=_(),ed=;q;--q){
  115. if(_()==){
  116. if(ed){
  117. cpy(ans,rt->s);
  118. dwt(ans);
  119. ed=;
  120. }
  121. printf("%d\n",(ans[_()]*iv[m]%P+P)%P);
  122. }else{
  123. ed=;
  124. int w=_(),x=_(),stp=;
  125. node*_w=ns+w,*stk[];
  126. for(node*a=_w;a!=nil;stk[++stp]=a,a=a->f);
  127. for(int i=stp;i>;--i){
  128. int*v1=stk[i]->ss,*v2=stk[i-]->s;
  129. fm(j)v1[j]-=v2[j];
  130. if(stk[i-]->isrt())div(stk[i]->v,stk[i]->vt,stk[i-]->l);
  131. }
  132. int*v1=x0[v0[w]],*v2=x0[x];
  133. fm(i)_w->v[i]=_w->v[i]*v1[i][iv]%P*v2[i]%P;
  134. _w->up();
  135. for(int i=;i<=stp;++i){
  136. int*v1=stk[i]->ss,*v2=stk[i-]->s;
  137. fm(j)v1[j]=(v1[j]+v2[j])%P;
  138. if(stk[i-]->isrt())mul(stk[i]->v,stk[i]->vt,stk[i-]->l);
  139. stk[i]->up();
  140. }
  141. v0[w]=x;
  142. }
  143. }
  144. return ;
  145. }

bzoj 4911: [Sdoi2017]切树游戏的更多相关文章

  1. 【BZOJ4911】[SDOI2017]切树游戏(动态dp,FWT)

    [BZOJ4911][SDOI2017]切树游戏(动态dp,FWT) 题面 BZOJ 洛谷 LOJ 题解 首先考虑如何暴力\(dp\),设\(f[i][S]\)表示当前以\(i\)节点为根节点,联通子 ...

  2. BZOJ4911: [Sdoi2017]切树游戏

    BZOJ 4911 切树游戏 重构了三次.jpg 每次都把这个问题想简单了.jpg 果然我还是太菜了.jpg 这种题的题解可以一眼秒掉了,FWT+动态DP简直是裸的一批... 那么接下来,考虑如何维护 ...

  3. LG3781 [SDOI2017]切树游戏

    题意 题目描述 小Q是一个热爱学习的人,他经常去维基百科学习计算机科学. 就在刚才,小Q认真地学习了一系列位运算符,其中按位异或的运算符\(\oplus\)对他影响很大.按位异或的运算符是双目运算符. ...

  4. LOJ2269 [SDOI2017] 切树游戏 【FWT】【动态DP】【树链剖分】【线段树】

    题目分析: 好题.本来是一道好的非套路题,但是不凑巧的是当年有一位国家集训队员正好介绍了这个算法. 首先考虑静态的情况.这个的DP方程非常容易写出来. 接着可以注意到对于异或结果的计数可以看成一个FW ...

  5. [SDOI2017]切树游戏

    题目 二轮毒瘤题啊 辣鸡洛谷竟然有卡树剖的数据 还是\(loj\)可爱 首先这道题没有带修,设\(dp_{i,j}\)表示以\(i\)为最高点的连通块有多少个异或和为\(j\),\(g_{i,j}=\ ...

  6. 洛谷 P3781 - [SDOI2017]切树游戏(动态 DP+FWT)

    洛谷题面传送门 SDOI 2017 R2 D1 T3,nb tea %%% 讲个笑话,最近我在学动态 dp,wjz 在学 FWT,而我们刚好在同一天做到了这道题,而这道题刚好又是 FWT+动态 dp ...

  7. 【LOJ】#2269. 「SDOI2017」切树游戏

    题解 把所有的数组一开始就FWT好然后再IFWT回去可以减小常数 从13s跑到0.7s-- 可以参照immortalCO的论文,感受一下毒瘤的动态动态DP 就是用数据结构维护线性递推的矩阵的乘积 由于 ...

  8. loj#2269. 「SDOI2017」切树游戏

    还是loj的机子快啊... 普通的DP不难想到,设F[i][zt]为带上根玩出zt的方案数,G[i][zt]为子树中的方案数,后面是可以用FWT优化的 主要是复习了下动态DP #include< ...

  9. LOJ2269. 「SDOI2017」切树游戏 [FWT,动态DP]

    LOJ 思路 显然是要DP的.设\(dp_{u,i}\)表示\(u\)子树内一个包含\(u\)的连通块异或出\(i\)的方案数,发现转移可以用FWT优化,写成生成函数就是这样的: \[ dp_{u}= ...

随机推荐

  1. 练习vue(用户管理)1

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. Linux内核分析-使用gdb跟踪调试内核从start_kernel到init进程启动

    姓名:江军 ID:fuchen1994 实验日期:2016.3.13 实验指导 使用实验楼的虚拟机打开shell cd LinuxKernel/ qemu -kernel linux-3.18.6/a ...

  3. python 枚举Enum类的使用

    1. 枚举的定义 首先,定义枚举要导入enum模块. 枚举定义用class关键字,继承Enum类. 示例代码: from enum import Enum class Color(Enum): red ...

  4. juery 安全加固 集合

    来源 jquery升级坑 2  3  4  5  版本  相关源码分享 新建document    jquery ajax使用说明 最近在iteye的新闻中看到jQuery已经更新到了1.6.1. 和 ...

  5. tmux安装与使用

    安装 用法 重点 一prefix前缀键 二window和pane的区分 tmux 按照官方给出的介绍是:终端复用工具.说白了就是可以仅仅在开启一个终端的情况下同时处理多个任务. 比如下面我设置的这样一 ...

  6. iOS被开发者遗忘在角落的NSException-其实它很强大

    NSException是什么? 最熟悉的陌生人,这是我对NSException的概述,为什么这么说呢?其实很多开发者接触到NSException的频率非常频繁,但很多人都不知道什么是NSExcepti ...

  7. tensorflow读取训练数据方法

    1. 预加载数据 Preloaded data # coding: utf-8 import tensorflow as tf # 设计Graph x1 = tf.constant([2, 3, 4] ...

  8. ubuntu16.04 下 NVIDIA GTX1050ti 显卡驱动 PPA安装

    本文参考资料链接: http://blog.csdn.net/10km/article/details/61191230 前几天在京东商城上花了6999元买了台笔记本(惠普(HP)暗影精灵II代Pro ...

  9. Oracle Tuning (Oracle 性能调整)的一些总结

    Oracle Tuning (Oracle 性能调整)的一些总结 Oracle Tuning (Oracle 性能调整)的一些总结关于Oracle的性能调整,一般包括两个方面,一是指Oracle数据库 ...

  10. 【图像处理】Haar-like特征

    特征提取的原理.代码等: 如果是白黑白,是减去一个黑的还是2个黑的,网上有不同的说法:应该需要看原论文了. 论文原文 The sum of the pixels which lie within th ...