• 【前后缀技巧】2022牛客多校3 A


    登录—专业IT笔试面试备考平台_牛客网

    题意:

    思路:

    这种是典中典中典,对于gcd,背包问题都是一样的处理方式

    预处理出前缀lca和后缀lca,枚举哪个消失即可,可以统计方案数

    Code:

    1. #include
    2. constexpr int N = 2e5 + 10;
    3. constexpr int mod = 1e9 + 7;
    4. constexpr int Inf = 0x3f3f3f3f;
    5. constexpr double eps = 1e-10;
    6. std::vector<int> adja[N], adjb[N];
    7. int n, k;
    8. int x[N];
    9. int a[N], b[N];
    10. int pa[N], pb[N];
    11. int depa[N], depb[N];
    12. int Fa[N][33], Fb[N][33];
    13. int prea[N], sufa[N], preb[N], sufb[N];
    14. void dfs1(int u, int fa) {
    15. depa[u] = depa[fa] + 1;
    16. Fa[u][0] = fa;
    17. for (int j = 1; j <= 30; j ++) Fa[u][j] = Fa[Fa[u][j - 1]][j - 1];
    18. for (auto v : adja[u]) {
    19. if (v == fa) continue;
    20. dfs1(v, u);
    21. }
    22. }
    23. void dfs2(int u, int fa) {
    24. depb[u] = depb[fa] + 1;
    25. Fb[u][0] = fa;
    26. for (int j = 1; j <= 30; j ++) Fb[u][j] = Fb[Fb[u][j - 1]][j - 1];
    27. for (auto v : adjb[u]) {
    28. if (v == fa) continue;
    29. dfs2(v, u);
    30. }
    31. }
    32. int lca_a(int u, int v) {
    33. if (depa[u] < depa[v]) std::swap(u, v);
    34. for (int j = 30; j >= 0; j --) {
    35. if (depa[Fa[u][j]] >= depa[v]) {
    36. u = Fa[u][j];
    37. }
    38. }
    39. if (u == v) return u;
    40. for (int j = 30; j >= 0; j --) {
    41. if (Fa[u][j] != Fa[v][j]) {
    42. u = Fa[u][j];
    43. v = Fa[v][j];
    44. }
    45. }
    46. return Fa[u][0];
    47. }
    48. int lca_b(int u, int v) {
    49. if (depb[u] < depb[v]) std::swap(u, v);
    50. for (int j = 30; j >= 0; j --) {
    51. if (depb[Fb[u][j]] >= depb[v]) {
    52. u = Fb[u][j];
    53. }
    54. }
    55. if (u == v) return u;
    56. for (int j = 30; j >= 0; j --) {
    57. if (Fb[u][j] != Fb[v][j]) {
    58. u = Fb[u][j];
    59. v = Fb[v][j];
    60. }
    61. }
    62. return Fb[u][0];
    63. }
    64. void solve() {
    65. std::cin >> n >> k;
    66. for (int i = 1; i <= k; i ++) std::cin >> x[i];
    67. for (int i = 1; i <= n; i ++) {
    68. std::cin >> a[i];
    69. }
    70. for (int i = 2; i <= n; i ++) {
    71. std::cin >> pa[i];
    72. adja[pa[i]].push_back(i);
    73. adja[i].push_back(pa[i]);
    74. }
    75. for (int i = 1; i <= n; i ++) {
    76. std::cin >> b[i];
    77. }
    78. for (int i = 2; i <= n; i ++) {
    79. std::cin >> pb[i];
    80. adjb[pb[i]].push_back(i);
    81. adjb[i].push_back(pb[i]);
    82. }
    83. dfs1(1, 0);
    84. dfs2(1, 0);
    85. prea[1] = x[1];
    86. for (int i = 2; i <= k; i ++) {
    87. prea[i] = lca_a(prea[i - 1], x[i]);
    88. }
    89. preb[1] = x[1];
    90. for (int i = 2; i <= k; i ++) {
    91. preb[i] = lca_b(preb[i - 1], x[i]);
    92. }
    93. sufa[k] = x[k];
    94. for (int i = k - 1; i >= 1; i --) {
    95. sufa[i] = lca_a(sufa[i + 1], x[i]);
    96. }
    97. sufb[k] = x[k];
    98. for (int i = k - 1; i >= 1; i --) {
    99. sufb[i] = lca_b(sufb[i + 1], x[i]);
    100. }
    101. int ans = 0;
    102. int cur1 = sufa[2];
    103. int cur2 = sufb[2];
    104. if (a[cur1] > b[cur2]) ans ++;
    105. for (int i = 2; i <= k - 1; i ++) {
    106. int cur1 = lca_a(prea[i - 1], sufa[i + 1]);
    107. int cur2 = lca_b(preb[i - 1], sufb[i + 1]);
    108. if (a[cur1] > b[cur2]) ans ++;
    109. };
    110. cur1 = prea[k - 1];
    111. cur2 = preb[k - 1];
    112. if (a[cur1] > b[cur2]) ans ++;
    113. std::cout << ans << "\n";
    114. }
    115. signed main() {
    116. std::ios::sync_with_stdio(false);
    117. std::cin.tie(nullptr);
    118. int t = 1;
    119. while(t --) {
    120. solve();
    121. }
    122. return 0;
    123. }

     

  • 相关阅读:
    成都理工大学_Python程序设计_第7章
    前端面试整理
    【0233】PG内核通过PG_TRY()、PG_CATCH()、PG_END_TRY()实现异常抛出、捕获
    【信号处理】基于蚁群优化随机共振检测附matlab代码
    Kafka消息可视化工具-Offset Explorer使用
    【VUEX】最好用的传参方式--Vuex的详解
    计算机毕设(附源码)JAVA-SSM基于的校园商城
    Redis有哪些数据结构?分别有哪些典型的应用场景?
    Windows10/11开启文件系统对大小写敏感
    浅谈开源和闭源的认知
  • 原文地址:https://blog.csdn.net/weixin_62528401/article/details/133565577