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;
    }
  • 相关阅读:
    4.2网络层提供的两种服务
    4.1网络层概述
    MATLAB曲面插值及交叉验证
    python爬虫成长之路(二):抓取代理IP并多线程验证
    KNN识别图像上的数字及python实现
    python爬虫成长之路(一):抓取证券之星的股票数据
    YARN环境搭建 之 一:CentOS7.0系统配置
    高效学习方法总结
    《立委随笔:机器学习和自然语言处理》
    XenServer安装虚拟机先扩容存放ISO镜像文件
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/10056246.html
Copyright © 2011-2022 走看看