• 剖分(树形差分)


    E-剖分_牛客小白月赛62 (nowcoder.com)

    题目描述
    牛牛有一颗包含n个结点的二叉树,这些结点编号为1 ...n。这颗树被定义为:1、以结点1为根。
    2、编号为α结点的两个儿子编号分别为:2 xa和2×巴+ 1。3、每个结点的权重初始都为0。
    牛牛接下来会对这颗树进行m次操作,操作的格式是以下四种之—:
    1、op a(这里op = 1)代表牛牛将以编号α为根结点的子树中所有结点的权重+1。

    2、op c(这里op = 2)    代表牛牛将以编号α为根结点的子树外的所有结点权重+1。

    3、op a(这里op = 3)代表牛牛将根结点到编号α结点的路径上的所有结点权重+1。
    4、op a:(这里op= 4)代表牛牛将根节点到编号α结点的路径上的结点之外的所有结点权重+1。
    牛妹想知道当牛牛的所有操作结束之后,树中权重为0,1,2 . ..m 的结点的数量分别是多少。
    输入描述:
    第一行输入两个空格分隔的整数: n m。
    接下来 m行,每行描述了一个牛牛进行的操作。保证:
    0 输出描述:
    输出一行共m+1个整数,代表答案。

    输入

    复制7 4 1 2 3 5 4 3 2 7

    7 4
    1 2
    3 5
    4 3
    2 7

    输出

    复制0 2 2 1 2

    0 2 2 1 2

    题解:

    利用差分的思想

    如果op = 1

    就是a[x] ++

    op = 2

    a[x] --

    op = 3

                while(x)
                {
                    b[x]++;
                    x/=2;
                }

    把一条链上的点都加1

    op = 4

    相当于把一条链上的点都减一

    a[1]++

        for(int i = 1;i <= n;i++)
        {
            a[i] += a[i/2];
        }

    每个点的值要加上层的标记(差分的思想)

    1. #include<iostream>
    2. #include<algorithm>
    3. #include<cstring>
    4. #include<string>
    5. #include<map>
    6. #include<vector>
    7. #include<queue>
    8. using namespace std;
    9. #define int long long
    10. //1 1 3 3 3
    11. int n,k,m;
    12. int a[10000400];
    13. int b[10000400];
    14. int c[10000400];
    15. void solve()
    16. {
    17. int n,m;
    18. cin >> n >>m;
    19. while(m--)
    20. {
    21. int op,x;
    22. cin >>op>>x;
    23. if(op == 1)
    24. {
    25. a[x]++;
    26. }
    27. else if(op == 2)
    28. {
    29. a[x]--;
    30. a[1]++;
    31. }
    32. else if(op == 3)
    33. {
    34. while(x)
    35. {
    36. b[x]++;
    37. x/=2;
    38. }
    39. }
    40. else
    41. {
    42. while(x)
    43. {
    44. b[x]--;
    45. x/=2;
    46. }
    47. a[1]++;
    48. }
    49. }
    50. for(int i = 1;i <= n;i++)
    51. {
    52. a[i] += a[i/2];
    53. }
    54. for(int i = 1;i <= n;i++)
    55. {
    56. c[a[i] + b[i]]++;
    57. }
    58. for(int i = 1;i <= n;i++)
    59. {
    60. cout<<c[i]<<"\n";
    61. }
    62. }
    63. signed main()
    64. {
    65. int t = 1;
    66. //cin >> t;
    67. ios::sync_with_stdio(false);
    68. cin.tie(0);
    69. cout.tie(0);
    70. while(t--)
    71. {
    72. solve();
    73. }
    74. }
    75. //4 8 12 16 20 24
    76. //
    77. //1 2 3 2
    78. //1 2 2 2 2 3
    79. //

  • 相关阅读:
    OneFlow-ONNX v0.6.0正式发布
    关于windows的文件监控管理系统(Java)
    AI与制药相结合,能否弯道超车
    21天学习挑战赛(3)设备树二进制文件DTB解析,DTB信息转化为 device_node 结构
    Spark - LeftOuterJoin 结果条数与左表条数不一致
    webSocket推送太快导致前端渲染卡顿问题优化
    当AI遇到IoT:开启智能生活的无限可能
    【uniapp】小程序开发,初始化项目vscode
    大学生职业生涯规划包word,ppt模板以及必备素材
    5款必备的电脑软件
  • 原文地址:https://blog.csdn.net/m0_64158084/article/details/128051560