[关闭]
@2368860385 2020-11-07T03:06:21.000000Z 字数 2871 阅读 199

day8

正睿停课


T1

上面的式子可以扩展到任意多个的情况,即:范德蒙卷积

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<iostream>
  6. #include<cctype>
  7. #include<set>
  8. #include<vector>
  9. #include<queue>
  10. #include<map>
  11. #define fi(s) freopen(s,"r",stdin);
  12. #define fo(s) freopen(s,"w",stdout);
  13. using namespace std;
  14. typedef long long LL;
  15. inline int read() {
  16. int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
  17. for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
  18. }
  19. const int mod = 998244353;
  20. const int N = 200005;
  21. const int Log = 18;
  22. int f[N][19], deth[N], head[N], nxt[N << 1], to[N << 1];
  23. int fac[N], ifac[N];
  24. int En;
  25. inline void add_edge(int u,int v) {
  26. ++En; to[En] = v; nxt[En] = head[u]; head[u] = En;
  27. ++En; to[En] = u; nxt[En] = head[v]; head[v] = En;
  28. }
  29. int ksm(int a,int b) {
  30. int res = 1;
  31. while (b) {
  32. if (b & 1) res = 1ll * res * a % mod;
  33. a = 1ll * a * a % mod;
  34. b >>= 1;
  35. }
  36. return res;
  37. }
  38. inline int C(int n,int m) {
  39. int t1 = fac[n], t2 = ifac[n - m], t3 = ifac[m];
  40. return 1ll * t1 * t2 % mod * t3 % mod;
  41. }
  42. void init(int n) {
  43. fac[0] = 1;
  44. for (int i=1; i<=n; ++i) fac[i] = 1ll * fac[i - 1] * i % mod;
  45. ifac[n] = ksm(fac[n], mod - 2);
  46. for (int i=n; i; --i) ifac[i - 1] = 1ll * ifac[i] * i % mod;
  47. }
  48. void dfs(int u,int fa) {
  49. deth[u] = deth[fa] + 1;
  50. for (int i=head[u]; i; i=nxt[i]) {
  51. int v = to[i];
  52. if (v == fa) continue;
  53. f[v][0] = u;
  54. dfs(v, u);
  55. }
  56. }
  57. int LCA(int u,int v) {
  58. int d = deth[u] - deth[v];
  59. for (int i=Log; i>=0; --i)
  60. if ((d >> i) & 1) u = f[u][i];
  61. if (u == v) return u;
  62. for (int i=Log; i>=0; --i)
  63. if (f[u][i] != f[v][i])
  64. u = f[u][i], v = f[v][i];
  65. return f[u][0];
  66. }
  67. int main() {
  68. int n = read();
  69. init(n);
  70. for (int i=1; i<n; ++i) {
  71. int u = read(), v = read();
  72. add_edge(u, v);
  73. }
  74. dfs(1, 0);
  75. for (int j=1; j<=Log; ++j)
  76. for (int i=1; i<=n; ++i)
  77. f[i][j] = f[f[i][j - 1]][j - 1];
  78. int m = read();
  79. for (int i=1; i<=m; ++i) {
  80. int u = read(), v = read(), len, ans = 0;
  81. if (deth[u] < deth[v]) swap(u, v);
  82. int lca = LCA(u, v);
  83. if (lca == v) {
  84. len = deth[u] - deth[lca];
  85. printf("%d\n", (ksm(ksm(2, len), mod - 2)) % mod);
  86. } else {
  87. int y = deth[u] - deth[lca], x = deth[v] - deth[lca];
  88. // for (int i=0; i<=x; ++i)
  89. // ans = (ans + 1ll * C(x, i) * C(y, i) % mod) % mod;
  90. ans = C(x + y, x);
  91. printf("%d\n",1ll * ans * ksm(ksm(2, x + y), mod - 2) % mod);
  92. }
  93. }
  94. return 0;
  95. }
  96. /*
  97. 3
  98. 1 2
  99. 1 3
  100. 2
  101. 3 1
  102. 3 2
  103. 5
  104. 5 4
  105. 4 1
  106. 4 3
  107. 1 2
  108. 3
  109. 3 1
  110. 5 3
  111. 5 1
  112. */

T2

  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<iostream>
  6. #include<cctype>
  7. #include<set>
  8. #include<vector>
  9. #include<queue>
  10. #include<map>
  11. #define fi(s) freopen(s,"r",stdin);
  12. #define fo(s) freopen(s,"w",stdout);
  13. using namespace std;
  14. typedef long long LL;
  15. inline int read() {
  16. int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
  17. for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
  18. }
  19. int p[1000005], a[10005], b[10005], dp[10005];
  20. // dp[i] 表示大小为i的石子,双方使用最有策略的情况的,先手的步数-后手的步数
  21. // 由于一个可以拆分的大小只能由A或者B
  22. // 那么对于一堆石子,如果只能由先手拆分,那么他会选择一个拆分方案最大的。
  23. // 只能由后手拆分的时候,他会拆分所有方案中最小的
  24. int main() {
  25. int n = read(), m = read();
  26. int tota = read();
  27. for (int i = 1; i <= tota; ++i) a[read()] = 1;
  28. int totb = read();
  29. for (int i = 1; i <= totb; ++i) b[read()] = 1;
  30. for (int i = 1; i <= n; ++i) p[i] = read();
  31. for (int i = 2; i <= m; ++i) {
  32. if (a[i]) {
  33. for (int j = 1; j <= i / 2; ++j)
  34. dp[i] = max(dp[i], dp[i - j] + dp[j] + 1);
  35. }
  36. if (b[i]) {
  37. for (int j = 1; j <= i / 2; ++j)
  38. dp[i] = min(dp[i], dp[i - j] + dp[j] - 1);
  39. }
  40. }
  41. int ans = 0;
  42. for (int i = 1; i <= n; ++i) ans += dp[p[i]];
  43. puts(ans > 0 ? "Pomegranate" : "Orange");
  44. return 0;
  45. }
  46. /*
  47. 2 3 1 1 1 2 1 3
  48. 3 5 2 5 4 3 1 3 2 5 1 1
  49. 5 7 3 5 3 7 2 2 6 6 4 6 6 2
  50. */
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注