CodeForces 190D. Non-Secret Cypher(思维)

题目链接
题意:给出n个元素的数列(n<=4e5),问有多少个子区间满足至少有一个数值出现至少K次。
解析:

#include 
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define pll pair
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define rep1(i,a,b) for(int i=a;i>=b;i--)
#define rson rt<<1|1,m+1,r
#define lson rt<<1,l,m
#define mod 323232323
using namespace std;
const int N=4e5+100;
int arr[N];
/*
    枚举到i
    设已经出现arr[i]的个数为num
    那么已经出现k次并且左端点最靠右的数字的
    左端点位置+1之前的位置
    到当前位置的区间都会加1

    如果num>=k
    那么从这个数字第num-k+2个位置之前的所有位置
    到当前位置的区间都会加1

    考虑到有重复的情况
    我们取这两个位置最大值即可
    所以我们可以设定一个最大值r
    如果出现》=k的情况就取最大值即可
*/
int main()
{
    #ifdef LOCAL_DEFINE
        freopen("D:\\rush.txt","r",stdin);
    #endif
    ios::sync_with_stdio(false),cin.tie(0);
    ll n,k,r=0,a;
    ll sum=0;
    cin>>n>>k;
    mappre;
    mapnext;
    maplmp;
    mapmp;
    rep(i,1,n)
    {
        cin>>a;
        if(pre[a]!=0)
            next[pre[a]]=i;
        pre[a]=i;
        if(lmp[a]==0)
            lmp[a]=i;
        mp[a]++;
        if(mp[a]==k)
        {
            r=max(r,lmp[a]);
        }
        else if(mp[a]>k)
        {
            lmp[a]=next[lmp[a]];
            r=max(r,lmp[a]);
        }
        sum+=r;
    }
    cout<

你可能感兴趣的:(codeforces)