cf220B莫队

用莫队比直接做快了很多。。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
#include<algorithm>
#define maxn 100005
int a[maxn],b[maxn],c[maxn],num[maxn];//原始数组,排序后的数组,离散后的数组,离散后的数组中元素出现的次数
int s;//块长度
struct Query{
    int l,r,id;
    bool operator<(const Query &a)const{
        if(l/s==a.l/s) return r<a.r;
        return l/s<a.l/s; 
    }
}q[maxn];
int ans[maxn];
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)==2){
        s=(int)sqrt(1.0*n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]),b[i]=a[i];
        sort(b+1,b+n+1);
        for(int i=1;i<=n;i++)
            c[i]=lower_bound(b+1,b+1+n,a[i])-b;
        for(int i=1;i<=m;i++)
            scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
        sort(q+1,q+m+1);
        //处理每个询问
        int l=1,r=0,tmp=0;
        for(int i=1;i<=m;i++){
            while(r<q[i].r){//右边界拓展
                r++;
                if(num[c[r]]==a[r]-1) tmp++;
                else if(num[c[r]]==a[r]) tmp--;
                num[c[r]]++; 
            }
            while(r>q[i].r){//右边界往回缩
                if(num[c[r]]==a[r]) tmp--;
                else if(num[c[r]]==a[r]+1) tmp++;
                num[c[r]]--;
                r--;
            }
            while(l<q[i].l){//左边界往回缩
                if(num[c[l]]==a[l]) tmp--;
                else if(num[c[l]]==a[l]+1) tmp++;
                num[c[l]]--;
                l++; 
            }
            while(l>q[i].l){//左边界拓展
                l--;
                if(num[c[l]]==a[l]-1) tmp++;
                else if(num[c[l]]==a[l]) tmp--;
                  num[c[l]]++;
            }
            ans[q[i].id]=tmp;
        }
        for(int i=1;i<=m;i++)
            printf("%d\n",ans[i]);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/zsben991126/p/9919373.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值