• Codeforces Round #833 (Div. 2) C. Zero-Sum Prefixes


     题目链接:Problem - C - Codeforces

    题目大意:

    t(1≤t≤10^4)组测试数据,每组给定数组长度n(1≤n≤2⋅10^5),和a1,a2,…,an(−10^9≤ai≤10^9)。

    可以做如下操作:

    选择一个ai=0的值,将其改为任意值。

    对于原数组的前缀和数组,定义score为前缀数组中为0的元素个数。

    问通过上述操作使得score最大为多少。

    样例:

    input:

    1. 5
    2. 5
    3. 2 0 1 -1 0
    4. 3
    5. 1000000000 1000000000 0
    6. 4
    7. 0 0 0 0
    8. 8
    9. 3 0 2 -10 10 -30 30 0
    10. 9
    11. 1 0 0 1 -1 0 1 0 -1

    output:

    1. 3
    2. 1
    3. 4
    4. 4
    5. 5

    思路:

    先求出初始前缀和数组s。

    抓住一个重要性质:对于一个可以修改的值,若ai等于0,它的修改只会影响前缀和数组中i及其以后的值。可以修改的点将s数组分为若干段,贪心的将每一段的score最大化即可。

    1.假设只有一个ai=0,设前缀和数组s[i~n]中出现次数最多的数为x,把它修改为-x即可保证最大化。

    2.如果有2个,ai=0,aj=0(i说明贪心策略并不影响j的决策。对于ai,只需要保证修改成s[i~j)中出现次数最多的数的相反数。

    3.对于多个,记录每个ai=0出现的位置,考虑相邻的两个i,j,对于第i个同理,只需要保证最大化s[i~j)即可。前面已经证明贪心策略并不会影响j之后的决策。

     代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #include
    15. #define pii pair
    16. #define pll pair
    17. #define pil pair
    18. #define pli pair
    19. #define pdd pair
    20. #define se second
    21. #define fi first
    22. #define endl '\n'
    23. #define rep(i,a,b) for (int i=a;i
    24. #define per(i,a,b) for (int i=a;i>b;--i)
    25. #define MEM(a,x) memset(a,x,sizeof(a))
    26. #define M(x) ((x)%MOD)
    27. #define db double
    28. #define eps 1e-9
    29. typedef long long LL;
    30. typedef unsigned long long ULL;
    31. using namespace std;
    32. const LL MOD=1004535809;
    33. const int N=2e5+10;
    34. int a[N];
    35. LL s[N];
    36. void solve()
    37. {
    38. int ans=0;
    39. int n;
    40. cin>>n;
    41. vector<int>v;
    42. rep(i,1,n+1){
    43. cin>>a[i],s[i]=s[i-1]+a[i];
    44. if(a[i]==0) v.push_back(i);
    45. }
    46. rep(i,0,v.size()){
    47. int ne;
    48. if(isize()-1) ne=v[i+1];
    49. else ne=n+1;
    50. int mx=0,val=0;
    51. mapint>mp;
    52. rep(j,v[i],ne){
    53. ++mp[s[j]];
    54. if(mp[s[j]]>mx) mx=mp[s[j]];
    55. }
    56. ans+=mx;
    57. }
    58. if(v.size()){
    59. rep(i,1,v[0]) if(s[i]==0) ++ans;
    60. }else rep(i,1,n+1) if(s[i]==0) ++ans;
    61. cout<
    62. }
    63. int main()
    64. {
    65. // #ifndef ONLINE_JUDGE
    66. // freopen("title.in","r",stdin);
    67. // freopen("title.out","w",stdout);
    68. // #endif
    69. ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    70. int _=1;
    71. cin>>_;
    72. while(_--){
    73. solve();
    74. }
    75. // rep(i,1,_+1){
    76. // cout<<"Case "<
    77. // solve();
    78. // }
    79. return 0;
    80. }

  • 相关阅读:
    Java基础面试整理
    JAVA --- Set
    【MySQL系列】MySQL数据库索引详解
    机器学习与模式识别作业1----吸烟者分类
    【代码随想录】-栈和队列专栏(Java)
    秋招面试!2022冲刺必看这1000道Java岗最新面试核心题,冲刺金九银十!!
    别走,这里有一份摸鱼小妙招,别人我不告诉他!
    【Leetcode】2369. 检查数组是否存在有效划分
    nodejs+Vue+python电子商务电商后台管理系统java
    GitHub爆热门!最全并发编程合集上线3分钟获星标180K
  • 原文地址:https://blog.csdn.net/qq_60256199/article/details/127839601