Codeforces Round 867 (Div. 3)

掉分md

D: 数学构造

E : 简单思维

F:图论,树 ,树的中心,维护对于树上每个点,到该点的最远距离是多少,板子

G:数学,计数

F:

题意:题意:树的收益是root(初始root=1)到最远的点的距离,更改相邻一个点成为root的要付出代价是c。    求最大利润

分析:只需维护出树上每个点与 距离最远的点的距离是多少。参考acwing树的中心,以及前不久div2 的一个D题也是这么做。

每个点当做root的收益 就是最远的点到自己的距离,减去成为根节点的代价(深度-1)  取最大值即可。

板子:求对于树上每一个点,最远的点到自己的距离是多少  max(d1[i],up[i])

  1. //dfs1
  2. //dfs2
  3. //维护出每一个点的深度
  4. //维护出每一个点到最远的点的距离
  5. //树的中心
  6. int deg[N]; //深度
  7. int d1[N],d2[N],p1[N],p2[N],up[N];
  8. void dfs1(int u,int fa)
  9. {
  10.     deg[u]=deg[fa]+1;
  11.     for(int i=h[u];i!=-1;i=ne[i])
  12.     {
  13.         int j=e[i];
  14.         if(j==fa)
  15.             continue;
  16.         dfs1(j,u);
  17.         if(1+d1[j]>=d1[u])
  18.         {
  19.             d2[u]=d1[u];
  20.             p2[u]=p1[u];
  21.             d1[u]=1+d1[j];
  22.             p1[u]=j;
  23.         }
  24.         else if(1+d1[j]>d2[u])
  25.         {
  26.             d2[u]=1+d1[j];
  27.             p2[u]=j;
  28.         }
  29.     }
  30. }
  31. void dfs2(int u,int fa)
  32. {
  33.     for(int i=h[u];i!=-1;i=ne[i])
  34.     {
  35.         int j=e[i];
  36.         if(j==fa)
  37.             continue;
  38.         if(p1[u]==j)
  39.             up[j]=1+max(up[u],d2[u]);
  40.         else
  41.             up[j]=1+max(up[u],d1[u]);
  42.         dfs2(j,u);
  43.     }
  44. }

  1. //dfs求代价
  2.     dfs1(1,0);
  3.     dfs2(1,0);
  4.     ll res=0;
  5.     for(int i=1;i<=n;i++)   //枚举这个点成为root的收益
  6.         res=max(res, (ll)k*max(up[i],d1[i])-((ll)deg[i]-1)*c );
  7.     cout<<res<<endl;

G

简单版本 G1 ai<=1e6

困难版本 G2 ai<=1e9

问有多少个三元组( i,j,k ) (允许相等)满足 存在b ,使得a[j]=a[i]*b, a[k]=a[j]*b

Easy verson:

遍历i, 遍历b 。直接计数 cnt[a[i]] *cnt[a[i]*b]*cnt[a[i]*b*b]即可

用数组计数,每次清空。 同时离散化去重应该会快一些

  1. sort(a.begin(),a.end());
  2.     a.erase(unique(a.begin(),a.end()) ,a.end());
  3.     int ma=a.back();
  4.     for(int i=0;i<a.size();i++)
  5.     {
  6.         if(cnt[a[i]]>=3)
  7.             res+=(ll)(cnt[a[i]])*(cnt[a[i]]-1)*(cnt[a[i]]-2);
  8.         for(int j=2;;j++)   //倍数
  9.         {
  10.             ll t1=(ll)a[i]*j;
  11.             ll t2=(ll)(a[i])*j*j;
  12.             if(t2>ma||t1>ma)
  13.                 break;
  14.             else if(cnt[t1]!=0&&cnt[t2]!=0)
  15.                 res+=(ll)cnt[a[i]]*cnt[t1]*cnt[t2];
  16.         }
  17.     }
  18.     cout<<res<<endl;
  19.     for(int i=0;i<a.size();i++)
  20.         cnt[a[i]]=0;
  21.     //清空
  22. }

竟然卡map, unordered_map能过。

G2  

困难版本: 区别,a[i]<=1e9,

统计 存在b,使得 a[i]*b=a[j],a[j]*b=a[k], 三元组( I,j,k)的个数

对于a[i]>=1e6的数, 枚举中间的数a[j],以及枚举b, 因为a[k]<=1e9;

所以b最多枚举1000

对于a[i]<=1e6的数,若固定a[i]或者固定a[j]枚举b的话,b的量级==(1e9)/a[i],量级可达很高,时间复杂度不可接受  这时可枚举a[j]的因子,因数分解的时间复杂度为根号a[i],时间复杂度为1000.可接受  总的复杂度为 n* 1000差不多

强调:longlong 的运算速度比int要慢,这题对时间卡的很极限,longlong大概率T掉

代码:服了,T49,再想想

  1.     //枚举中间数a[j]  //计数a[j]/b,a[j],a[j]*b;
  2.     //计数
  3.     int ma=a.back();
  4.     for(int i=0;i<a.size();i++)
  5.     {
  6.         if(mp[a[i]]>=3)
  7.             res+=(ll)mp[a[i]]*(mp[a[i]]-1)*(mp[a[i]]-2);
  8.         if(a[i]==1)
  9.             continue;
  10.        
  11.         if(a[i]<=1e6)
  12.         {
  13.             //质因数分解
  14.             //枚举它的所有因数
  15.             for(int j=1;j<=a[i]/j;j++)
  16.             {
  17.                 if(a[i]%j==0)
  18.                 {
  19.                     if((ll)a[i]/j*a[i]<=ma)
  20.                         res+= (ll)mp[j]*mp[a[i]]*mp[a[i]/j*a[i]];
  21.      
  22.                     if(j!=1&&a[i]/j!=j)
  23.                     {
  24.                         int j1=a[i]/j;
  25.                         if((ll)a[i]/j1*a[i]<=ma)
  26.                         res+= (ll)mp[j1]*mp[a[i]]*mp[a[i]/j1*a[i]];
  27.                     }
  28.                 }
  29.             }
  30.         }
  31.         else
  32.         {
  33.             for(int b=2;b<=ma/a[i];b++)
  34.             {
  35.                 if(a[i]%b!=0)
  36.                     continue;
  37.                 if((ll)a[i]*b<=ma)
  38.                 res+= (ll)mp[a[i]/b ]*mp[a[i]]*mp[a[i]*b ];
  39.             }
  40.         }
  41.     }
  42.     cout<<res<<endl;
  43. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值