[关闭]
@ZCDHJ 2019-09-24T03:50:13.000000Z 字数 3127 阅读 376

Codeforces986E Prince's Problem

未分类


先将每个询问差分为询问从根到点的路径 之积,然后 dfs 树一遍离线处理。对于 可以看成是对于 的每个质因子的指数取 min,因为 内质数个数不多且指数小,可以开个桶来统计。具体来说,加入一个 时将 的桶里编号从 的部分加一,统计 的时候将 的每种质因子及其个数算出来(表示为 ),统计 的桶里 的总和即为答案里这种质因子的指数。为了快速地实现质因数分解先用线性筛求出每个数最小的质因子,即可 完成单次分解。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <vector>
  4. const int MAXN = 1e5;
  5. const int MAXV = 1e7;
  6. const int MOD = 1e9 + 7;
  7. struct Query {
  8. int id, x, v;
  9. Query() : id(0), x(0), v(0) {}
  10. Query(int _id, int _x, int _v) : id(_id), x(_x), v(_v) {}
  11. };
  12. int n, m, prime_tot, edge, idx;
  13. int prime[MAXV | 1], min_prime[MAXV | 1], prime_id[MAXV | 1], fst[MAXN | 1], a[MAXN | 1], ans[MAXN | 1];
  14. int dfn[MAXN | 1], topf[MAXN | 1], father[MAXN | 1], size[MAXN | 1], son[MAXN | 1], depth[MAXN | 1];
  15. short book[25][664580];
  16. bool vis[MAXV | 1];
  17. std::vector < Query > queries[MAXN | 1];
  18. struct Edge {
  19. int to, nxt;
  20. Edge() : to(0), nxt(0) {}
  21. Edge(int a, int b) : to(b), nxt(fst[a]) {}
  22. } e[MAXN << 1 | 1];
  23. inline int read( ){
  24. register int x = 0;
  25. register char ch = getchar();
  26. while (!isdigit(ch)) ch = getchar();
  27. while (isdigit(ch)) {
  28. x = x * 10 + ch - '0';
  29. ch = getchar();
  30. }
  31. return x;
  32. }
  33. inline void addEdge(int a, int b) {
  34. e[++edge] = Edge(a, b);
  35. fst[a] = edge;
  36. }
  37. void dfs1(int x, int y) {
  38. father[x] = y;
  39. depth[x] = depth[y] + 1;
  40. dfn[x] = ++idx;
  41. size[x] = 1;
  42. for (int k = fst[x]; k; k = e[k].nxt) {
  43. int to = e[k].to;
  44. if (to == y) continue;
  45. dfs1(to, x);
  46. size[x] += size[to];
  47. if (size[to] > size[son[x]]) son[x] = to;
  48. }
  49. }
  50. void dfs2(int x, int ftop) {
  51. topf[x] = ftop;
  52. if (!son[x]) return;
  53. dfs2(son[x], ftop);
  54. for (int k = fst[x]; k; k = e[k].nxt) {
  55. int to = e[k].to;
  56. if (to == father[x] || to == son[x]) continue;
  57. dfs2(to, to);
  58. }
  59. }
  60. int LCA(int x, int y) {
  61. while (topf[x] != topf[y]) {
  62. if (depth[topf[x]] < depth[topf[y]]) std::swap(x, y);
  63. x = father[topf[x]];
  64. }
  65. return depth[x] < depth[y] ? x : y;
  66. }
  67. int fast_pow(int x, int y, int mod) {
  68. int res = 1, base = x;
  69. while (y > 0) {
  70. if (y & 1) res = 1LL * res * base % mod;
  71. base = 1LL * base * base % mod;
  72. y >>= 1;
  73. }
  74. return res;
  75. }
  76. void update(int x, int v) {
  77. while (x != 1) {
  78. int times = 0;
  79. int min = min_prime[x];
  80. // printf("x=%d min=%d\n", x, min_prime[x]);
  81. while (x != 1 && min_prime[x] == min) {
  82. ++times;
  83. x /= min_prime[x];
  84. }
  85. for (int i = 1; i <= times; ++i) book[i][prime_id[min]] += v;
  86. }
  87. }
  88. int query(int v) {
  89. int res = 1;
  90. while (v != 1) {
  91. int times = 0;
  92. int min = min_prime[v];
  93. while (v != 1 && min_prime[v] == min) {
  94. ++times;
  95. v /= min_prime[v];
  96. }
  97. int sum = 0;
  98. for (int i = 1; i <= times; ++i) sum += book[i][prime_id[min]];
  99. res = 1LL * res * fast_pow(min, sum, MOD) % MOD;
  100. }
  101. return res;
  102. }
  103. void calc_dfs(int x) {
  104. update(a[x], 1);
  105. for (int k = fst[x]; k; k = e[k].nxt) {
  106. int to = e[k].to;
  107. if (to == father[x]) continue;
  108. calc_dfs(to);
  109. }
  110. for (std::vector < Query > :: iterator it = queries[x].begin(); it != queries[x].end(); ++it) {
  111. Query now = *it;
  112. int res = query(now.x);
  113. if (now.v == 1) ans[now.id] = 1LL * ans[now.id] * res % MOD;
  114. else ans[now.id] = 1LL * ans[now.id] * fast_pow(res, MOD - 2, MOD) % MOD;
  115. }
  116. update(a[x], -1);
  117. }
  118. int main() {
  119. n = read();
  120. for (int i = 1; i < n; ++i) {
  121. int u = read(), v = read();
  122. addEdge(u, v);
  123. addEdge(v, u);
  124. }
  125. for (int i = 1; i <= n; ++i) a[i] = read();
  126. for (int i = 2; i <= 1e7; ++i) {
  127. if (!vis[i]) {
  128. prime[++prime_tot] = i;
  129. min_prime[i] = i;
  130. prime_id[i] = prime_tot;
  131. }
  132. for (int j = 1; i * prime[j] <= 1e7 && j <= prime_tot; ++j) {
  133. vis[i * prime[j]] = 1;
  134. min_prime[i * prime[j]] = prime[j];
  135. if (i % prime[j] == 0) break;
  136. }
  137. }
  138. dfs1(1, 0);
  139. dfs2(1, 1);
  140. m = read();
  141. for (int i = 1; i <= m; ++i) {
  142. ans[i] = 1;
  143. int a = read(), b = read(), x = read();
  144. int lca = LCA(a, b);
  145. queries[a].push_back(Query(i, x, 1));
  146. queries[b].push_back(Query(i, x, 1));
  147. queries[lca].push_back(Query(i, x, -1));
  148. queries[father[lca]].push_back(Query(i, x, -1));
  149. }
  150. calc_dfs(1);
  151. for (int i = 1; i <= m; ++i) printf("%d\n", ans[i]);
  152. return 0;
  153. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注