Little Elephant and Array CodeForces - 220B(莫队、离散化)

https://vjudge.net/problem/CodeForces-220B

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<set>
#include<map>
#include<vector>
#include<string.h>
#include<queue>
#include<cmath>
#define mem(a, b) memset(a, b, sizeof(a))
#define LL long long
#define N 100001
#define MOD
using namespace std;
int n, m, a[N], bl[N], block, ans, rep[N], cnt, vis[N];
struct node{
	int l, r, id, ans;
}q[N]; 
bool cmp1(node x, node y) {
	if(x.l/block==y.l/block) return x.r<y.r;
	return x.l<y.l; 
}

bool cmp2(node x, node y) {
	return x.id<y.id;
}

int get(int x) {
	return lower_bound(rep+1, rep+1+cnt, x)-rep;
}

void mo() {//莫队 
	int l=1, r=0, tl, tr, ans=0;
	a[0]=-1;
	for(int i=1; i<=m; i++) {
		tl=q[i].l, tr=q[i].r;
		while(l<tl) {//如果l<rl,那么l要往右移,如果当前的a[l]符合条件,移动后,数量减一,就会不符合,所以答案减一 
			if(vis[bl[l]]==a[l]) ans--; 
			vis[bl[l]]--;//如果减去a[l]的个数,符合条件,答案加一 
			if(vis[bl[l]]==a[l]) ans++;
			l++;
		}
		while(l>tl) {
			l--;
			if(vis[bl[l]]==a[l]) ans--;
			vis[bl[l]]++;
			if(vis[bl[l]]==a[l]) ans++;
		}
		while(r>tr) {
			if(vis[bl[r]]==a[r]) ans--;
			vis[bl[r]]--;
			if(vis[bl[r]]==a[r]) ans++;
			r--;
		}
		while(r<tr) {
			r++;
			if(vis[bl[r]]==a[r]) ans--;
			vis[bl[r]]++;
			if(vis[bl[r]]==a[r]) ans++;
		}
		q[i].ans=ans;
	} 
} 

int main() {
	scanf("%d%d",&n, &m);
	block=sqrt(n);
	for(int i=1; i<=n; i++){
		scanf("%d",&a[i]);
		rep[i]=a[i];//离散化 
	}	
	for(int i=1; i<=m; i++){
		scanf("%d%d", &q[i].l, &q[i].r);
		q[i].id=i;
	}
	sort(rep+1, rep+1+n);//先排序 
	cnt=unique(rep+1, rep+1+n)-rep-1;//去重 
	for(int i=1; i<=n; i++){
		bl[i]=get(a[i]);//离散化 
	}
	sort(q+1, q+1+m, cmp1);
	mo();
	sort(q+1, q+1+m, cmp2);
	for(int i=1; i<=m; i++){
		printf("%d\n", q[i].ans);
	}
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值