• 思维+启发式合并


    活动地址:CSDN21天学习挑战赛

    D - Magical Array

    昨天确实没想到这个思路,操作1的话需要看一下i-1,i,j,j+1的前缀和,进行完1操作之后,i-1减少了1,i没变,j减少了1,j+1没变,总的前缀和的总和是没变的,而操作2的话多了一个j+2,也就是说j+1减少了1,j+2没变,但前缀和的总和是减少了1的,所以可以用这个发现去得出答案

    CodeTON Round 2 (Div. 1 + Div. 2) D(前缀和) E(DP) - 知乎 (zhihu.com)

    1. #include
    2. #define ll long long
    3. #define lowbit(x) ((x)&(-x))
    4. using namespace std;
    5. const ll MAX=1e6+5;
    6. const ll mod=998244353;
    7. ll t,n,m,sum[100005];
    8. int main(){
    9. scanf("%lld",&t);
    10. while(t--){
    11. scanf("%lld%lld",&n,&m);
    12. for(int i=1;i<=n;i++) sum[i]=0;
    13. for(int i=1;i<=n;i++){
    14. ll pre=0;
    15. for(int j=1;j<=m;j++){
    16. ll x;scanf("%lld",&x);
    17. pre+=x;
    18. sum[i]+=pre;
    19. }
    20. }
    21. ll mx=*max_element(sum+1,sum+n+1),mi=*min_element(sum+1,sum+n+1);
    22. ll id=min_element(sum+1,sum+n+1)-sum;
    23. printf("%lld %lld\n",id,mx-mi);
    24. }
    25. system("pause");
    26. return 0;
    27. }

    1256D - Binary String Minimizing

    可以发现只要将0尽可能地向前挪动即可,直接计算出距离然后看看剩下的步数是否足够,不够就前进剩下的步数,然后退出

    1. #include
    2. #define ll long long
    3. #define lowbit(x) ((x)&(-x))
    4. using namespace std;
    5. const ll MAX=1e6+5;
    6. const ll mod=998244353;
    7. ll t,n,k;
    8. string s;
    9. int main(){
    10. scanf("%lld",&t);
    11. while(t--){
    12. scanf("%lld%lld",&n,&k);
    13. cin>>s;
    14. ll ze=0;
    15. for(int i=0;i
    16. if(s[i]=='0'){
    17. if(i-ze<=k){k-=i-ze;swap(s[ze],s[i]);ze++;}
    18. else {swap(s[i],s[i-k]);break;}
    19. }
    20. }
    21. cout<
    22. }
    23. system("pause");
    24. return 0;
    25. }

    1327C - Game with Chips

    一道挺有意思的题,乍一看像是多个点的搜索,但是最多可以走2nm步,这个数字的含义是可以绕整个地图两圈,所以我们可以先把所有点聚集到1,1上,这个步骤花费n-m-2步,然后再绕地图走一圈即可,实践证明都可以这样走,所以其实没有-1这玩意(我一开始还傻傻的写了个搜索,,)

    1. #include
    2. #define ll long long
    3. #define lowbit(x) ((x)&(-x))
    4. using namespace std;
    5. const ll MAX=1e6+5;
    6. const ll mod=998244353;
    7. ll n,m,k,flag,vis[205][205],vs[205][205];
    8. ll dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
    9. string op[4]={"R","L","D","U"};
    10. struct node{
    11. ll x,y;
    12. }f[205],ss[205];
    13. string ans;
    14. void dfs(ll x,ll y,ll cnt,string s){
    15. if(s.size()>2*n*m-n-m+2) return;
    16. if(cnt>=k){
    17. ans+=s;
    18. flag=1;return;
    19. }
    20. if(flag) return;
    21. for(int i=0;i<4;i++){
    22. ll tx=x+dx[i],ty=y+dy[i],val,vss;
    23. if(!vis[tx][ty]&&tx>=1&&tx<=n&&ty>=1&&ty<=m){
    24. vis[tx][ty]=1;vss=vs[tx][ty];
    25. if(vs[tx][ty]) val=1,vs[tx][ty]=0;
    26. else val=0;
    27. dfs(tx,ty,cnt+val,s+op[i]);
    28. vis[tx][ty]=0;vs[tx][ty]=vss;
    29. }
    30. }
    31. }
    32. int main(){
    33. scanf("%lld%lld%lld",&n,&m,&k);
    34. for(int i=1;i<=k;i++) scanf("%lld%lld",&ss[i].x,&ss[i].y);
    35. for(int i=1;i<=k;i++) scanf("%lld%lld",&f[i].x,&f[i].y),vs[f[i].x][f[i].y]=1;
    36. ll kk=0;
    37. for(int i=1;i<=n;i++)
    38. for(int j=1;j<=m;j++)
    39. if(vs[i][j]) kk++;
    40. k=kk;
    41. ans="";
    42. for(int i=1;i"L";
    43. for(int i=1;i"U";
    44. if(n*m-1>=n+m-2){
    45. for(int i=1;i<=n;i++){
    46. for(int j=1;j
    47. if(i&1) ans+="R";
    48. else ans+="L";
    49. }
    50. if(i!=n) ans+="D";
    51. }
    52. cout<size()<<"\n"<"\n";
    53. return 0;
    54. }
    55. // ll cnt=0;
    56. // if(vs[1][1]) vs[1][1]=0,cnt++;
    57. // vis[1][1]=1;
    58. // dfs(1,1,cnt,"");
    59. // if(!flag) printf("-1\n");
    60. // else{
    61. // cout<
    62. // }
    63. system("pause");
    64. return 0;
    65. }

    741D - Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths启发式合并

    这个很搞的题目需要的知识:异或在树上的应用,非常熟练的启发式合并;

    字母都转换为2进制的形式(1<<(s[0]-'a'),Xor[u]存的是u到1的异或和,u,v这条路径的异或和就是Xor[u]^Xor[v],f[xor[u]]表示的是Xor[u]这个异或值的最大深度,三种更新答案的方式:1.子树的最大路径;2.子树根与子树中某一点的最大路径;3.子树中某两点的路径。

    丫的,改了一晚上也没改出来,题解讲的挺不错的,代码真是不大好看,当然也有自己弱鸡的原因在,但是在这么难的题目中,一篇好题解都没有,我也是没想到

    我是伞兵!!!

    我是伞兵!!!

    我是伞兵!!!

    题解 CF741D 【Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths】 - Arextre 的博客 - 洛谷博客

    1. #include
    2. #define ll long long
    3. #define lowbit(x) ((x)&(-x))
    4. using namespace std;
    5. const ll MAX=1e6+5;
    6. const ll MAXSIZE=1<<22;
    7. const ll mod=998244353;
    8. ll n,c[500005],f[MAXSIZE+5],ans[500005],son[500005],siz[500005],Xor[500005],fson;
    9. ll cnt,head[1000006];
    10. struct Edge{
    11. ll from,to,next,w;
    12. }edge[1000006];
    13. void addedge(ll from, ll to,ll w){
    14. edge[++cnt].from = from;
    15. edge[cnt].to = to;
    16. edge[cnt].w=w;
    17. edge[cnt].next =head[from];
    18. head[from] = cnt;
    19. }
    20. void dfs1(ll u){
    21. siz[u]=1,son[u]=0;
    22. for(int i=head[u];i;i=edge[i].next){
    23. int v=edge[i].to;
    24. Xor[v]=Xor[u]^edge[i].w;
    25. dfs1(v);
    26. siz[u]+=siz[v];
    27. if(siz[v]>siz[son[u]])son[u]=v;
    28. }
    29. }
    30. void cal(ll u,ll d,ll keep){
    31. if(keep==1) f[Xor[u]]=max(f[Xor[u]],d);
    32. else f[Xor[u]]=0;
    33. for(int i=head[u];i;i=edge[i].next){
    34. ll j=edge[i].to;
    35. cal(j,d+1,keep);
    36. }
    37. }
    38. //rtd为一开始的子树根节点的深度
    39. ll dfs3(ll u,ll d,ll rtd){
    40. ll res=0;
    41. if(f[Xor[u]]) res=max(res,f[Xor[u]]+d-(rtd<<1));
    42. for(int i=0;i<22;i++)
    43. if(f[Xor[u]^(1<max(res,f[Xor[u]^(1<1));
    44. for(int i=head[u];i;i=edge[i].next){
    45. ll j=edge[i].to;
    46. res=max(res,dfs3(j,d+1,rtd));
    47. }
    48. return res;
    49. }
    50. void dfs2(ll u,ll d){
    51. for(int i=head[u];i;i=edge[i].next){
    52. int v=edge[i].to;
    53. if(v!=son[u]){
    54. dfs2(v,d+1);
    55. ans[u]=max(ans[u],ans[v]);
    56. cal(v,d+1,-1);
    57. }
    58. }
    59. if(son[u]) dfs2(son[u],d+1),ans[u]=max(ans[u],ans[son[u]]);
    60. if(f[Xor[u]]) ans[u]=max(ans[u],f[Xor[u]]-d);
    61. for(int i=0;i<22;i++)
    62. if(f[Xor[u]^(1<max(ans[u],f[Xor[u]^(1<
    63. f[Xor[u]]=max(d,f[Xor[u]]);
    64. for(int i=head[u];i;i=edge[i].next){
    65. ll j=edge[i].to;
    66. if(j!=son[u]){
    67. ans[u]=max(dfs3(j,d+1,d),ans[u]);cal(j,d+1,1);
    68. }
    69. }
    70. }
    71. int main(){
    72. scanf("%lld",&n);
    73. for(int i=2;i<=n;i++){
    74. char s[3];
    75. ll x;
    76. scanf("%lld %s",&x,s);
    77. addedge(x,i,1<<(s[0]-'a'));
    78. }
    79. dfs1(1);
    80. dfs2(1,0);
    81. for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
    82. system("pause");
    83. return 0;
    84. }

  • 相关阅读:
    维控PLC——LX1S :编程口通讯协议
    unity2022版本 实现加减进度条
    操作系统 、人、 宇宙
    Boost库学习笔记(三)内存对齐模块
    哲学家干饭问题 C++
    [newstarctf2023] --RE wp
    Spring Retry 重试
    web3.0 nft 是什么? nft的意义是什么?
    docker、docker-compose安装教程,很详细
    多通道LMMSE图像超分辨复原方法研究-附Matlab代码
  • 原文地址:https://blog.csdn.net/weixin_52621204/article/details/126101286