luogu4135 作诗

这里

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
int n, c, m, a[100005], bel[100005], blc, f[325][325], sum[325][100005], cnt[100005];
int uu, vv, ans;
int query(int uu, int vv){
    int re=0;
    if(bel[uu]==bel[vv]){
        for(int i=uu; i<=vv; i++)   cnt[a[i]] = 0;
        for(int i=uu; i<=vv; i++){
            cnt[a[i]]++;
            if(!(cnt[a[i]]&1))  re++;
            else if(cnt[a[i]]>2)    re--;
        }
    }
    else{
        re = f[bel[uu]+1][bel[vv]-1];
        for(int i=uu; i<=bel[uu]*blc; i++)
            cnt[a[i]] = sum[bel[vv]-1][a[i]] - sum[bel[uu]][a[i]];
        for(int i=(bel[vv]-1)*blc+1; i<=vv; i++)
            cnt[a[i]] = sum[bel[vv]-1][a[i]] - sum[bel[uu]][a[i]];
        for(int i=uu; i<=bel[uu]*blc; i++){
            cnt[a[i]]++;
            if(!(cnt[a[i]]&1))  re++;
            else if(cnt[a[i]]>2)    re--;
        }
        for(int i=(bel[vv]-1)*blc+1; i<=vv; i++){
            cnt[a[i]]++;
            if(!(cnt[a[i]]&1))  re++;
            else if(cnt[a[i]]>2)    re--;
        }
    }
    return re;
}
int main(){
    cin>>n>>c>>m;
    blc = sqrt(n);
    for(int i=1; i<=n; i++){
        scanf("%d", &a[i]);
        bel[i] = (i - 1) / blc + 1;
    }
    for(int i=1; i<=n; i++){
        if(i==(bel[i]-1)*blc+1){
            for(int j=1; j<=c; j++)
                sum[bel[i]][j] = sum[bel[i]-1][j];
        }
        sum[bel[i]][a[i]]++;
    }
    for(int i=1; i<=bel[n]; i++){
        memset(cnt, 0, sizeof(cnt));
        int now=0;
        for(int j=(i-1)*blc+1; j<=n; j++){
            cnt[a[j]]++;
            if(!(cnt[a[j]]&1))  now++;
            else if(cnt[a[j]]>2)    now--;
            f[i][bel[j]] = now;
        }
    }
    while(m--){
        scanf("%d %d", &uu, &vv);
        uu = (uu + ans) % n + 1;
        vv = (vv + ans) % n + 1;
        if(uu>vv)   swap(uu, vv);
        ans = query(uu, vv);
        printf("%d\n", ans);
    }
    return 0;
}

转载于:https://www.cnblogs.com/poorpool/p/8503809.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值