codeforces 813e 莫队算法

来源:互联网 发布:设置数据库单用户模式 编辑:程序博客网 时间:2024/06/05 08:50

题意:给你一个区间 问你有总共多少个元素 ? 但是有一个条件 就是如果这个元素超过k个 当k个来算

思路:由于题目限制,所以只能是在线算法。如果知道一个区间,往左端加入一个点,只要知道这个的往右数第k个和它相同的数是否在这个区间么就可以了,右端同理。然后计算了一下复杂度和条件,发现可以使用莫队算法。

ps:其实可以使用在线的主席树,当时没想到,而且由于只记得莫队算法的思想,所以写了一个奇怪(偷懒版)的莫队算法,姿势其实并不标准,网络上有很多讲解的。


#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<stack>#include<vector>#include<queue>using namespace std;#define LL long long#define MAX 100010vector<int> f[MAX];vector<int> b[MAX];int l[MAX];int r[MAX];int s[400][400];int a[MAX];int v[MAX];int main(){    int n,k;    scanf("%d%d",&n,&k);    for(int i=1;i<=n;i++)    {        scanf("%d",&a[i]);        f[a[i]].push_back(i);        if(f[a[i]].size()>k)        {            l[i]=f[a[i]][f[a[i]].size()-k-1];        }    }    for(int i=n;i>=1;i--)    {        b[a[i]].push_back(i);        if(b[a[i]].size()>k)        {            r[i]=b[a[i]][b[a[i]].size()-k-1];        }        else            r[i]=n+1;    }    for(int i=0;i*300<n;i++)    {        int sum=0;        memset(v,0,sizeof(v));        for(int j=i*300+1;j<=n;j++)        {            v[a[j]]++;            if(v[a[j]]<=k)                sum++;            if(j%300==0)                s[i][j/300]=sum;        }    }    int m,x,y;    int ans=0;    scanf("%d",&m);    for(int i=0;i<m;i++)    {        scanf("%d%d",&x,&y);        x=(ans+x)%n+1;        y=(ans+y)%n+1;        if(x>y)            swap(x,y);        if(y-x<600)        {            ans=0;            memset(v,0,sizeof(v));            for(int j=x;j<=y;j++)            {                v[a[j]]++;                if(v[a[j]]<=k)                    ans++;            }        }        else{            int nowl=(x/300+1)-(x%300==1);            int nowr=y/300;            ans=s[nowl][nowr];            int L=nowl*300+1;            int R=nowr*300;            while(L>x){                L--;                if(r[L]>R)                    ans++;            }            while(R<y){                R++;                if(l[R]<x)                    ans++;            }        }        printf("%d\n",ans);    }return 0;}


阅读全文
1 0
原创粉丝点击