zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 55 (Rated for Div. 2):E. Increasing Frequency

    E. Increasing Frequency

    题目链接:https://codeforces.com/contest/1082/problem/E

    题意:

    给出n个数以及一个c,现在可以对一个区间上的数同时加上或减去一个值,问最后c的最多数量为多少。

    题解:

    这题挺有意思的,我们通过分析题目可以发现,对于每一个d,如果把[l,r]里面的d都变为c,则最后c的数量为cnt(c,1,l-1)+cnt(c,r+1,n)+cnt(d,l,r)。

    这个式子变化一下,有:cnt(c,1,n)+cnt(d,l,r)-cnt(c,l,r)。

    现在就只需要维护cnt(d,l,r)-cnt(c,l,r)的最大值就可以了。

    这里有许多种维护方式,我说下我用的。

    假设a[x1]=a[x2]=...a[xn]=d,那么对于[x1+1,x2-1]...[xn+1,n]这些区间,是没有d的,则我们需要维护的值就变为了-cnt(c,l,r),这里就相当于把连续的区间缩成了一个点。

    为什么能缩点?我理解的就是选择的区间是一段连续的区间,缩点后的每个点,只要把当前的点加上的和为正(此时把当前连续的区间选完)就可以选择这一个点,否则就直接以下一个点为起点(当前区间就一个不选,之前已经保存了一个最大值了)。

    所以对于一段连续的没有d的区间,要么选择连续的一段区间,要么直接不选,所以缩点后,用最大连续子段和的技巧就可以了~

    代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 1e6 ;
    int a[N];
    int cnt[N];
    int n,c,ans=-1;
    vector <int> pos[N];
    int calc(int x){
        if(x==c) return 0;
        vector <int> vec;
        int len = pos[x].size();
        if(len<=0) return 0;
        vec.push_back(-cnt[pos[x][0]-1]);
        vec.push_back(1);
        for(int i=1;i<len;i++){
            vec.push_back(-cnt[pos[x][i]-1]+cnt[pos[x][i-1]]);
            vec.push_back(1);
            if(i==len-1) vec.push_back(-cnt[n]+cnt[pos[x][i]]);
        }
        int tot = 0,sum = 0,l = vec.size();
        for(int i=0;i<l;i++){
            sum+=vec[i];
            if(sum>=tot){
                tot=sum;
            }else if(sum<0) sum=0;
        }
        return max(tot,sum);
    }
    int main(){
        scanf("%d%d",&n,&c);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            cnt[i]=cnt[i-1]+(a[i]==c);
            pos[a[i]].push_back(i);
        }
        for(int i=1;i<=N-5;i++){
            ans=max(calc(i)+cnt[n],ans);
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    BZOJ1033:[ZJOI2008]杀蚂蚁antbuster(模拟)
    BZOJ4001:[TJOI2015]概率论(卡特兰数,概率期望)
    BZOJ1820:[JSOI2010]Express Service 快递服务(DP)
    BZOJ4066:简单题(K-D Tree)
    2110. [NOIP2015普及]金币
    73. 找最佳通路
    cogs 7. 通信线路
    codevs 3295 落单的数
    151. [USACO Dec07] 建造路径
    必备算法之二叉树的相关操作
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10056246.html
Copyright © 2011-2022 走看看