[关闭]
@dxbdly 2022-08-17T12:48:55.000000Z 字数 8054 阅读 242

8-16暑期模拟赛

2022暑


期望得分:

T1 T2 T3 Sum
100 40 60 200

实际得分:

T1 T2 T3 Sum
0 0 50 50

T1 dostavljac

思维难度 ,代码难度

1.题意

给你一棵 个节点的树,每个时刻你可以获得当前节点的权值,或者移动到相邻的节点上,每个节点不能重复获得权值,问从节点 开始,经过 时刻,最多能获得多少权值。

考试的时候出问题最大的题吧。

2.解析

模型很显然,树形背包类的题,考虑最后结束的时候不会回到根,所以要记录回/不回根的状态

很好求:

但是考场上求 的时候脑子晕掉了,考虑钦定一个儿子不回来后,一直在优化剩下儿子回来的求和柿子。

最后想到一个,预处理出前缀的背包以及后缀的背包,然后把两个背包合并的做法,感觉好像也是对的,但是十分复杂。

正确的做法应该是直接讨论当前儿子是否回来:

边界:


  1. //The Code Is From Dawn
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. inline int read() {
  5. int x = 0;
  6. char c = getchar();
  7. bool f = 0;
  8. while(!isdigit(c)) f |= (c == '-'), c = getchar();
  9. while(isdigit(c)) x = (x * 10) + (c ^ 48), c = getchar();
  10. return f ? -x : x;
  11. }
  12. const int maxn = 505;
  13. int n, m;
  14. int a[maxn];
  15. struct node {
  16. int v, nex;
  17. }edge[maxn << 1];
  18. int head[maxn], len;
  19. int f[maxn][maxn], g[maxn][maxn];
  20. inline void make_map(int u, int v) {
  21. len++;
  22. edge[len].nex = head[u];
  23. edge[len].v = v;
  24. head[u] = len;
  25. }
  26. inline void Search(int x, int fa) {
  27. f[x][0] = g[x][0] = 0;
  28. f[x][1] = g[x][1] = a[x];
  29. for(register int i = head[x]; i; i = edge[i].nex) {
  30. int y = edge[i].v;
  31. if(y == fa) continue;
  32. Search(y, x);
  33. for(register int j = m; j >= 0; --j)
  34. for(register int k = m - j; k >= 0; --k) {
  35. if(j + k + 2 <= m) g[x][j + k + 2] = max(g[x][j + k + 2], g[y][k] + g[x][j]), f[x][j + k + 2] = max(f[x][j + k + 2], g[y][k] + f[x][j]);
  36. if(j + k + 1 <= m) f[x][j + k + 1] = max(f[x][j + k + 1], f[y][k] + g[x][j]);
  37. }
  38. }
  39. }
  40. int main() {
  41. // freopen("dostavljac.in", "r", stdin);
  42. // freopen("dostavljac.out", "w", stdout);
  43. n = read(), m = read();
  44. for(register int i = 1; i <= n; ++i) a[i] = read();
  45. for(register int i = 1; i < n; ++i) {
  46. int u = read(), v = read();
  47. make_map(u, v), make_map(v, u);
  48. }
  49. Search(1, 0);
  50. printf("%d\n", f[1][m]);
  51. return 0;
  52. }

3.总结

感觉还是树形背包做的不够到位吧。

T2 range

思维难度:,代码难度:

1.题意

,其中

不保证 为质数

2.解析

后面两题都是那种点子题,奇奇怪怪的。

麻烦的地方在于不能求逆元,所以只能合并区间。

考虑类似分块的做法,把每 个当成一块,然后把前后两个块的后缀与前缀拼一下就能得到答案。

经典想到了就水题,但是不知道为啥就是想不到。

  1. //The Code Is From Dawn
  2. #define fastcall __attribute__((optimize("-O3")))
  3. #pragma GCC optimize(1)
  4. #pragma GCC optimize(2)
  5. #pragma GCC optimize(3)
  6. #pragma GCC optimize("Ofast")
  7. #pragma GCC optimize("inline")
  8. #pragma GCC optimize("-fgcse")
  9. #pragma GCC optimize("-fgcse-lm")
  10. #pragma GCC optimize("-fipa-sra")
  11. #pragma GCC optimize("-ftree-pre")
  12. #pragma GCC optimize("-ftree-vrp")
  13. #pragma GCC optimize("-fpeephole2")
  14. #pragma GCC optimize("-ffast-math")
  15. #pragma GCC optimize("-fsched-spec")
  16. #pragma GCC optimize("unroll-loops")
  17. #pragma GCC optimize("-falign-jumps")
  18. #pragma GCC optimize("-falign-loops")
  19. #pragma GCC optimize("-falign-labels")
  20. #pragma GCC optimize("-fdevirtualize")
  21. #pragma GCC optimize("-fcaller-saves")
  22. #pragma GCC optimize("-fcrossjumping")
  23. #pragma GCC optimize("-fthread-jumps")
  24. #pragma GCC optimize("-funroll-loops")
  25. #pragma GCC optimize("-fwhole-program")
  26. #pragma GCC optimize("-freorder-blocks")
  27. #pragma GCC optimize("-fschedule-insns")
  28. #pragma GCC optimize("inline-functions")
  29. #pragma GCC optimize("-ftree-tail-merge")
  30. #pragma GCC optimize("-fschedule-insns2")
  31. #pragma GCC optimize("-fstrict-aliasing")
  32. #pragma GCC optimize("-fstrict-overflow")
  33. #pragma GCC optimize("-falign-functions")
  34. #pragma GCC optimize("-fcse-skip-blocks")
  35. #pragma GCC optimize("-fcse-follow-jumps")
  36. #pragma GCC optimize("-fsched-interblock")
  37. #pragma GCC optimize("-fpartial-inlining")
  38. #pragma GCC optimize("no-stack-protector")
  39. #pragma GCC optimize("-freorder-functions")
  40. #pragma GCC optimize("-findirect-inlining")
  41. #pragma GCC optimize("-fhoist-adjacent-loads")
  42. #pragma GCC optimize("-frerun-cse-after-loop")
  43. #pragma GCC optimize("inline-small-functions")
  44. #pragma GCC optimize("-finline-small-functions")
  45. #pragma GCC optimize("-ftree-switch-conversion")
  46. #pragma GCC optimize("-foptimize-sibling-calls")
  47. #pragma GCC optimize("-fexpensive-optimizations")
  48. #pragma GCC optimize("-funsafe-loop-optimizations")
  49. #pragma GCC optimize("inline-functions-called-once")
  50. #pragma GCC optimize("-fdelete-null-pointer-checks")
  51. #include<bits/stdc++.h>
  52. using namespace std;
  53. inline int read() {
  54. int x = 0;
  55. char c = getchar();
  56. bool f = 0;
  57. while(!isdigit(c)) f |= (c == '-'), c = getchar();
  58. while(isdigit(c)) x = (x * 10) + (c ^ 48), c = getchar();
  59. return f ? -x : x;
  60. }
  61. const int maxn = 2 * 1e7 + 5;
  62. int n, k, P;
  63. int A, B, C, D;
  64. int S[maxn], Pre[maxn], Suf[maxn];
  65. int main() {
  66. // freopen("range.in", "r", stdin);
  67. // freopen("range.out", "w", stdout);
  68. n = read(), k = read(), P = read();
  69. A = read(), B = read(), C = read(), D = read();
  70. S[0] = A;
  71. for(register int i = 1; i < n; ++i) S[i] = (1ll * S[i - 1] * B + C) % D;
  72. for(register int i = 0; i < n; ++i)
  73. if(i % k) Pre[i] = 1ll * Pre[i - 1] * S[i] % P;
  74. else Pre[i] = S[i] % P;
  75. for(register int i = n - 1; i >= 0; --i)
  76. if(i % k != k - 1) Suf[i] = 1ll * Suf[i + 1] * S[i] % P;
  77. else Suf[i] = S[i] % P;
  78. int Answer = 0;
  79. for(register int i = 0; i + k - 1 < n; ++i)
  80. if(i % k) Answer ^= 1ll * Suf[i] * Pre[i + k - 1] % P;
  81. else Answer ^= Suf[i];
  82. printf("%d\n", Answer);
  83. return 0;
  84. }

T3 random

思维难度:,代码难度:

1.题意

对于一个长度为 的数组 ,定义其特征值为 。给你一个长度为 的数组 ,求其所有子串的特征值的最小值。

2.解析

考虑当区间的长度 变长,那么差的绝对值一定变小。

考虑双指针,如果当前的 小于 ,那么把左端点往后移,否则把右端点往后移。

考虑怎么维护 ,开个 ,答案必然在相邻的两个作差。

所以每次维护这些差,删除和插入都把他左右两边的值修改一下。

这维护属实点子,新奇。

  1. //The Code Is From Dawn
  2. #define fastcall __attribute__((optimize("-O3")))
  3. #pragma GCC optimize(1)
  4. #pragma GCC optimize(2)
  5. #pragma GCC optimize(3)
  6. #pragma GCC optimize("Ofast")
  7. #pragma GCC optimize("inline")
  8. #pragma GCC optimize("-fgcse")
  9. #pragma GCC optimize("-fgcse-lm")
  10. #pragma GCC optimize("-fipa-sra")
  11. #pragma GCC optimize("-ftree-pre")
  12. #pragma GCC optimize("-ftree-vrp")
  13. #pragma GCC optimize("-fpeephole2")
  14. #pragma GCC optimize("-ffast-math")
  15. #pragma GCC optimize("-fsched-spec")
  16. #pragma GCC optimize("unroll-loops")
  17. #pragma GCC optimize("-falign-jumps")
  18. #pragma GCC optimize("-falign-loops")
  19. #pragma GCC optimize("-falign-labels")
  20. #pragma GCC optimize("-fdevirtualize")
  21. #pragma GCC optimize("-fcaller-saves")
  22. #pragma GCC optimize("-fcrossjumping")
  23. #pragma GCC optimize("-fthread-jumps")
  24. #pragma GCC optimize("-funroll-loops")
  25. #pragma GCC optimize("-fwhole-program")
  26. #pragma GCC optimize("-freorder-blocks")
  27. #pragma GCC optimize("-fschedule-insns")
  28. #pragma GCC optimize("inline-functions")
  29. #pragma GCC optimize("-ftree-tail-merge")
  30. #pragma GCC optimize("-fschedule-insns2")
  31. #pragma GCC optimize("-fstrict-aliasing")
  32. #pragma GCC optimize("-fstrict-overflow")
  33. #pragma GCC optimize("-falign-functions")
  34. #pragma GCC optimize("-fcse-skip-blocks")
  35. #pragma GCC optimize("-fcse-follow-jumps")
  36. #pragma GCC optimize("-fsched-interblock")
  37. #pragma GCC optimize("-fpartial-inlining")
  38. #pragma GCC optimize("no-stack-protector")
  39. #pragma GCC optimize("-freorder-functions")
  40. #pragma GCC optimize("-findirect-inlining")
  41. #pragma GCC optimize("-fhoist-adjacent-loads")
  42. #pragma GCC optimize("-frerun-cse-after-loop")
  43. #pragma GCC optimize("inline-small-functions")
  44. #pragma GCC optimize("-finline-small-functions")
  45. #pragma GCC optimize("-ftree-switch-conversion")
  46. #pragma GCC optimize("-foptimize-sibling-calls")
  47. #pragma GCC optimize("-fexpensive-optimizations")
  48. #pragma GCC optimize("-funsafe-loop-optimizations")
  49. #pragma GCC optimize("inline-functions-called-once")
  50. #pragma GCC optimize("-fdelete-null-pointer-checks")
  51. #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
  52. #include<bits/stdc++.h>
  53. #define int long long
  54. using namespace std;
  55. int read(){
  56. int s=0,f=0;
  57. char ch=getchar();
  58. while(!isdigit(ch)){
  59. f|=ch=='-';
  60. ch=getchar();
  61. }
  62. while(isdigit(ch)){
  63. s=(s<<1)+(s<<3)+(ch^48);
  64. ch=getchar();
  65. }
  66. return f?-s:s;
  67. }
  68. const int maxn = 1e6 + 5, INF = 1e9 + 7;
  69. int n;
  70. int a[maxn];
  71. multiset <int> S, Ans;
  72. inline void Insert(int x) {
  73. Ans.erase(Ans.lower_bound(*(S.lower_bound(x))-*(--S.lower_bound(x))));
  74. Ans.insert(*S.lower_bound(x)-x);
  75. Ans.insert(x-*(--S.lower_bound(x)));
  76. S.insert(x);
  77. }
  78. inline void Erase(int x) {
  79. S.erase(S.lower_bound(x));
  80. Ans.erase(Ans.lower_bound(*S.lower_bound(x)-x));
  81. Ans.erase(Ans.lower_bound(x-*(--S.lower_bound(x))));
  82. Ans.insert(*S.lower_bound(x)-*(--S.lower_bound(x)));
  83. }
  84. inline void Work() {
  85. int Answer = INF, l = 1, r = 2;
  86. while(l <= n && r <= n) {
  87. if(r - l + 1 >= 2) Answer = min(Answer, max(*Ans.begin(), r - l + 1));
  88. if(*Ans.begin() > (r - l + 1) || r - l + 1 < 2) Insert(a[++r]);
  89. else Erase(a[(++l) - 1]);
  90. }
  91. printf("%lld\n", Answer);
  92. }
  93. signed main() {
  94. // freopen("random.in", "r", stdin);
  95. // freopen("random.out", "w", stdout);
  96. n = read();
  97. for(register int i=1;i<=n;i++) a[i] = read();
  98. S.insert(INT_MAX), S.insert(-INT_MAX), Ans.insert(2ll*INT_MAX);
  99. Insert(a[1]), Insert(a[2]);
  100. Work();
  101. return 0;
  102. }

3.总结

单调性不一定二分,有时候双指针也很好用。

对于后两题这种点子题,嗯多打CF(

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注