题意:一棵带边权的树,边权可单边修改,问初始时和每次修改后有多少条路径$\gcd=1$

首先考虑用反演求答案,设$f(n)$为路径$\gcd=n$的路径条数,$g(n)$为路径$\gcd$是$n$倍数的路径条数,那么$g(n)=\sum\limits_{n|d}f(d)$,所以$f(n)=\sum\limits_{d|n}\mu\left(\frac dn\right)g(d)$,答案就是$f(1)=\sum\limits_{d}\mu(d)g(d)$

我们现在要求$g(d)$,先考虑没有修改怎么做,我们对每个$d$预处理出是$d$倍数的那些边(这里可以直接枚举边权的约数,因为边权$\leq10^6$)用这些边构图,答案就是每个连通块的$\binom{siz}2$之和,这里可以用并查集做

加上修改就只预处理那些不被修改的边,先用这些不被修改的边建并查集,每次对第$i$个询问,修改第$1\cdots i$条边的边权后再把这至多$q$条边插进并查集中,再统计答案

总时间复杂度貌似是$O(wq^2\log n)$???但是加一些小优化好像可以过...

  1. #include<stdio.h>
  2. #include<vector>
  3. using namespace std;
  4. typedef long long ll;
  5. const int T=1000000;
  6. int pr[T+10],mu[T+10];
  7. bool np[T+10];
  8. void sieve(){
  9. int i,j,M=0;
  10. mu[1]=1;
  11. for(i=2;i<=T;i++){
  12. if(!np[i]){
  13. pr[++M]=i;
  14. mu[i]=-1;
  15. }
  16. for(j=1;j<=M&&i*pr[j]<=T;j++){
  17. np[i*pr[j]]=1;
  18. if(i%pr[j]==0)break;
  19. mu[i*pr[j]]=-mu[i];
  20. }
  21. }
  22. }
  23. struct edge{
  24. int x,y,w;
  25. }E[100010];
  26. struct ask{
  27. int i,v;
  28. }Q[110];
  29. bool del[100010],us[T+10];
  30. vector<int>G[T+10];
  31. ll C;
  32. int fa[100010],dep[100010],siz[100010],M;
  33. struct oper{
  34. int u,f,d,s;
  35. oper(int _u=0,int _f=0,int _d=0,int _s=0){u=_u;f=_f;d=_d;s=_s;}
  36. }stk[200010];
  37. void add(int u){
  38. stk[++M]=oper(u,fa[u],dep[u],siz[u]);
  39. }
  40. int get(int x){
  41. while(x!=fa[x])x=fa[x];
  42. return x;
  43. }
  44. void merge(int x,int y){
  45. x=get(x);
  46. y=get(y);
  47. if(x==y)return;
  48. if(dep[x]<dep[y])swap(x,y);
  49. add(x);
  50. add(y);
  51. fa[y]=x;
  52. if(dep[x]==dep[y])dep[x]++;
  53. C+=(ll)siz[x]*siz[y];
  54. siz[x]+=siz[y];
  55. }
  56. void roll(){
  57. int u=stk[M].u;
  58. fa[u]=stk[M].f;
  59. dep[u]=stk[M].d;
  60. siz[u]=stk[M].s;
  61. M--;
  62. }
  63. ll ans[110];
  64. int val[100010];
  65. int main(){
  66. int n,q,i,j,k,tM;
  67. ll tC;
  68. sieve();
  69. scanf("%d",&n);
  70. for(i=1;i<n;i++)scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].w);
  71. scanf("%d",&q);
  72. for(i=1;i<=q;i++){
  73. scanf("%d%d",&Q[i].i,&Q[i].v);
  74. del[Q[i].i]=1;
  75. }
  76. for(i=1;i<n;i++){
  77. if(!del[i]){
  78. for(j=1;j*j<=E[i].w;j++){
  79. if(E[i].w%j==0){
  80. G[j].push_back(i);
  81. if(j*j!=E[i].w)G[E[i].w/j].push_back(i);
  82. }
  83. }
  84. }else{
  85. for(j=1;j*j<=E[i].w;j++){
  86. if(E[i].w%j==0)us[j]=us[E[i].w/j]=1;
  87. }
  88. }
  89. }
  90. for(i=1;i<=q;i++){
  91. for(j=1;j*j<=Q[i].v;j++){
  92. if(Q[i].v%j==0)us[j]=us[Q[i].v/j]=1;
  93. }
  94. }
  95. for(i=1;i<=n;i++){
  96. fa[i]=i;
  97. dep[i]=1;
  98. siz[i]=1;
  99. }
  100. for(i=1;i<=T;i++){
  101. if(mu[i]&&!(G[i].empty()&&!us[i])){
  102. C=0;
  103. M=0;
  104. for(int j:G[i])merge(E[j].x,E[j].y);
  105. tM=M;
  106. tC=C;
  107. for(j=1;j<=q;j++)val[Q[j].i]=E[Q[j].i].w;
  108. for(j=0;j<=q;j++){
  109. val[Q[j].i]=Q[j].v;
  110. C=tC;
  111. if(us[i]){
  112. for(k=1;k<=q;k++){
  113. if(val[Q[k].i]%i==0)merge(E[Q[k].i].x,E[Q[k].i].y);
  114. }
  115. }
  116. ans[j]+=mu[i]*C;
  117. while(M>tM)roll();
  118. }
  119. while(M)roll();
  120. }
  121. }
  122. for(i=0;i<=q;i++)printf("%lld\n",ans[i]);
  123. }

[CODECHEF]TREECNT2的更多相关文章

  1. 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1288  Solved: 490 ...

  2. 【BZOJ4260】 Codechef REBXOR 可持久化Trie

    看到异或就去想前缀和(⊙o⊙) 这个就是正反做一遍最大异或和更新答案 最大异或就是很经典的可持久化Trie,从高到低贪心 WA: val&(1<<(base-1))得到的并不直接是 ...

  3. codechef 两题

    前面做了这场比赛,感觉题目不错,放上来. A题目:对于数组A[],求A[U]&A[V]的最大值,因为数据弱,很多人直接排序再俩俩比较就过了. 其实这道题类似百度之星资格赛第三题XOR SUM, ...

  4. codechef January Challenge 2014 Sereja and Graph

    题目链接:http://www.codechef.com/JAN14/problems/SEAGRP [题意] 给n个点,m条边的无向图,判断是否有一种删边方案使得每个点的度恰好为1. [分析] 从结 ...

  5. BZOJ3509: [CodeChef] COUNTARI

    3509: [CodeChef] COUNTARI Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 339  Solved: 85[Submit][St ...

  6. CodeChef CBAL

    题面: https://www.codechef.com/problems/CBAL 题解: 可以发现,我们关心的仅仅是每个字符出现次数的奇偶性,而且字符集大小仅有 26, 所以我们状态压缩,记 a[ ...

  7. CodeChef FNCS

    题面:https://www.codechef.com/problems/FNCS 题解: 我们考虑对 n 个函数进行分块,设块的大小为S. 每个块内我们维护当前其所有函数值的和,以及数组中每个元素对 ...

  8. codechef Prime Distance On Tree(树分治+FFT)

    题目链接:http://www.codechef.com/problems/PRIMEDST/ 题意:给出一棵树,边长度都是1.每次任意取出两个点(u,v),他们之间的长度为素数的概率为多大? 树分治 ...

  9. BZOJ 3221: [Codechef FEB13] Obserbing the tree树上询问( 可持久化线段树 + 树链剖分 )

    树链剖分+可持久化线段树....这个一眼可以看出来, 因为可持久化所以写了标记永久化(否则就是区间修改的线段树的持久化..不会), 结果就写挂了, T得飞起...和管理员拿数据调后才发现= = 做法: ...

随机推荐

  1. Python脚本 - 常用单位转换

    测试系统为:Centos 6.7 Python版本为: 3.6.4 脚本功能:常用单位的转换,这里用内存来模拟 import pstuil def bytes2human(n): symbols = ...

  2. 宿主机mount虚拟机镜像文件

    转载 mount挂载虚拟机镜像文件 使用mount挂载ubuntu虚拟机所在的img文件的时候,执行: “sudo mount -o loop xxx.img /mnt/xxx”, 系统提示: “mo ...

  3. 原始套接字&&数据链路层访问

    1. 原始套接字能力: (1) 进程可以读写ICMP,IGMP等分组,如ping程序: (2) 进程可以读写内核不处理协议字段的ipv4数据报:如OSPF等: (3) 进程可以使用IP_HDRINCL ...

  4. U-Boot启动过程完全分析<转>

    转载自:http://www.cnblogs.com/heaad/archive/2010/07/17/1779829.html 1.1       U-Boot工作过程 U-Boot启动内核的过程可 ...

  5. openfire在内网的情况下 文件传输代理的设置

    openfire在内网的情况下 文件传输代理的设置 http://blog.csdn.net/v6543210/article/details/22506565

  6. Jmeter跨线程组传递变量

    请求API需要授权令牌,但是授权令牌只需要获取一次,即可调用服务器上其他业务接口. 所以我想要把授权操作放在单独的一个线程,业务流放在其他线程. 这就需要我把从授权线程获取的令牌传入业务流线程. 解决 ...

  7. Android 开发之避免被第三方使用代理抓包

    现象:charles抓不到包,但wireshark,HttpAnalyzor可以抓到包. 关键代码: URL url = new URL(urlStr); urlConnection = (HttpU ...

  8. sicily 1001. Fibonacci 2

    1001. Fibonacci 2   Description In the Fibonacci integer sequence, F0 = 0, F1 = 1, and Fn = Fn-1 + F ...

  9. 【hihocoder】sam-3

    把Parent Tree拓扑排序下,然后从下往上合并. 具体的看官方题解啦~ #include<bits/stdc++.h> #define N 1000010 using namespa ...

  10. artdialog自定义多个按钮

    在实际运用到的过程中artdialog弹出框下面的按钮不止一个 可以自己定义多个按钮 function view_show(cust_id){$.dialog({        id: 'view_c ...