• D - Range = √Sum 构造,F - Strange Memory 树上启发式合并


    D - Range = √Sum 构造

    当n为偶数的时候可以让将n划分为n/2个组,让每一个组的两个数和为2*n,这样n个数的和就是n^2,所以只需要让最大值和最小值差为n就可以了,那就从首部和尾部分别开始构造,前一半是n-n/2,n-n/2+1,,,;后一半是n+n/2,n+n/2-1,,,;

    当n为奇数的话,考虑将n这个值作为数组的中间元素,然后让数组中的数公差为1的来构造,这样最大值和最小值差为n-1,这样构造出来的和为n^2,然后再将整个数组+2,和就为n^2+2*n,然后将最大值+1,最小值-1,最大值与最小值的差值为n+1,为了让和为n^2+2*n+1,还需要让倒数第二个数+1,这是合法的,因为前一步已经让最大值+1了,所以不会有相同的数

    Codeforces Round #836 (Div. 2) Editorial - Codeforces

    1. #include
    2. //#pragma-GCC-optimize("-Ofast");
    3. #define int long long
    4. #define ll __int128
    5. #define lowbit(x) ((x)&(-x))
    6. #define endl '\n'
    7. #define pause system("pause")
    8. using namespace std;
    9. const int N=2e6+5;
    10. const int mod=1e9+7;
    11. const int inf=1e18;
    12. const int up=1e6;
    13. const double pi=acos(-1);
    14. int qpow(int a,int b)
    15. {
    16. int res=1;
    17. while(b)
    18. {
    19. if(b&1) res=res*a%mod;
    20. a=a*a%mod;
    21. b>>=1;
    22. }
    23. return res;
    24. }
    25. int getinv(int a){return qpow(a,mod-2);}
    26. int t,n,ans[N];
    27. signed main()
    28. {
    29. ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    30. cin>>t;
    31. while(t--)
    32. {
    33. cin>>n;
    34. if(n&1)
    35. {
    36. ans[n/2+1]=n;
    37. int cnt=1;
    38. for(int i=n/2;i>=1;i--) ans[i]=n-cnt++;
    39. cnt=1;
    40. for(int i=n/2+2;i<=n;i++) ans[i]=n+cnt++;
    41. for(int i=1;i<=n;i++) ans[i]+=2;
    42. ans[1]--;ans[n]++;ans[n-1]++;
    43. }
    44. else
    45. {
    46. ans[1]=n-n/2;ans[n]=n+n/2;
    47. int cnt=1;
    48. for(int i=2;i<=n/2;i++) ans[i]=n-n/2+cnt++;
    49. cnt=1;
    50. for(int i=n-1;i>n/2;i--) ans[i]=n+n/2-cnt++;
    51. }
    52. for(int i=1;i<=n;i++) cout<" ";
    53. cout<
    54. }
    55. return 0;
    56. }

    F - Strange Memory 树上启发式合并

    结论:两个数的异或等于这两个数的二进制按位异或再加起来

    比如 1101^1001=000^ 1000+100^000+00^00+1^1;

    可以发现对于u和u的祖宗是不会满足条件的,即满足条件的是一定是u和另外子树的点,所以我们可以一个子树一个子树的来算,算完一个子树就将这个子树的信息统计下来,开一个num[a[u]][i][0/1]的数组,表示a[u]的第i位是0或是1的有多少个,算一个点u就可以把u拆成二进制将按位来算最后加起来就可以,对于子树信息的统计用启发式合并就可以了

    F. Strange Memory__7许的博客-CSDN博客

    1. #include
    2. //#pragma-GCC-optimize("-Ofast");
    3. //#define int long long
    4. #define ll long long
    5. #define lowbit(x) ((x)&(-x))
    6. #define endl '\n'
    7. #define pause system("pause")
    8. using namespace std;
    9. const int N=2e5+5;
    10. const int mod=1e9+7;
    11. const int inf=1e18;
    12. const int up=1e6;
    13. const double pi=acos(-1);
    14. int qpow(int a,int b)
    15. {
    16. int res=1;
    17. while(b)
    18. {
    19. if(b&1) res=res*a%mod;
    20. a=a*a%mod;
    21. b>>=1;
    22. }
    23. return res;
    24. }
    25. int getinv(int a){return qpow(a,mod-2);}
    26. int head[N],cnt;
    27. struct Edge
    28. {
    29. int next,to;
    30. }e[N];
    31. void addedge(int from,int to)
    32. {
    33. e[++cnt].next=head[from];
    34. e[cnt].to=to;
    35. head[from]=cnt;
    36. }
    37. const ll maxu=(1<<20);
    38. int n,son[N],num[maxu][21][2],siz[N],fson,a[N];
    39. ll ans;
    40. vector<int>g;
    41. void dfs(int u,int fa)
    42. {
    43. siz[u]=1;
    44. for(int i=head[u];i;i=e[i].next)
    45. {
    46. int j=e[i].to;
    47. if(j==fa) continue;
    48. dfs(j,u);
    49. siz[u]+=siz[j];
    50. if(siz[j]>siz[son[u]]) son[u]=j;
    51. }
    52. }
    53. void add(int u,int val)
    54. {
    55. for(int i=0;i<=20;i++)
    56. {
    57. num[a[u]][i][(u>>i)&1]+=val;
    58. }
    59. }
    60. void del(int u,int fa)
    61. {
    62. for(int i=head[u];i;i=e[i].next)
    63. {
    64. int j=e[i].to;
    65. if(j==fa) continue;
    66. del(j,u);
    67. }
    68. add(u,-1);
    69. }
    70. int query(int u,int val)
    71. {
    72. int res=0;
    73. for(int i=0;i<=20;i++)
    74. {
    75. int bit=!((u>>i)&1);
    76. res+=num[val][i][bit]*(1LL<
    77. }
    78. return res;
    79. }
    80. void cal(int u,int fa,int lca)
    81. {
    82. g.push_back(u);
    83. ans+=query(u,a[u]^a[lca]);
    84. for(int i=head[u];i;i=e[i].next)
    85. {
    86. int j=e[i].to;
    87. if(j==fa||j==fson) continue;
    88. cal(j,u,lca);
    89. }
    90. }
    91. void dsu(int u,int fa,int keep)
    92. {
    93. for(int i=head[u];i;i=e[i].next)
    94. {
    95. int j=e[i].to;
    96. if(j!=fa&&j!=son[u]) dsu(j,u,0);
    97. }
    98. if(son[u]) dsu(son[u],u,1),fson=son[u];
    99. for(int i=head[u];i;i=e[i].next)//把根节点当作lca去算子树中的每一个点
    100. {
    101. int j=e[i].to;
    102. if(j==fa||j==fson) continue;
    103. cal(j,u,u);
    104. for(auto x:g)
    105. add(x,1);
    106. g.clear();
    107. }
    108. add(u,1);
    109. fson=0;
    110. if(!keep) del(u,fa);
    111. }
    112. signed main()
    113. {
    114. ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    115. cin>>n;
    116. for(int i=1;i<=n;i++) cin>>a[i];
    117. for(int i=1;i
    118. {
    119. int u,v;cin>>u>>v;
    120. addedge(u,v);
    121. addedge(v,u);
    122. }
    123. dfs(1,0);
    124. dsu(1,0,1);
    125. cout<
    126. return 0;
    127. }

  • 相关阅读:
    ESP-IDF工程自定义组件
    ARM Cortex-M3从汇编到C,从Boot到应用的教程
    Vue3 中使用 TypeScript --- 给 Vue 中的 数据 标注类型
    联合投稿其乐融融 抖音共创助你大显身手
    位于kernel的文件系统大管家--Virtual File System
    ViLT Vision-and-Language Transformer Without Convolution or Region Supervision
    docker 构建并运行 python项目
    css自定义属性
    设置HTTP代理隧道
    JS中递归函数
  • 原文地址:https://blog.csdn.net/weixin_52621204/article/details/128091871