P1972 [SDOI2009]HH的项链

洛谷的分块练习题

看到讨论中说分块莫队被卡就写了树状数组...(但感觉做法和莫队的思想有点像?)

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+7;
const int M=1e6+7;
int c[N],a[N],n,m;
struct node{
	int l,r,ans,id;
}q[N];
bool cmp(node a,node b){//按r排序
	return a.r==b.r?a.l<b.l:a.r<b.r;
}
bool cmpp(node a,node b){
	return a.id<b.id;
}
void add(int x,int y){
	while(x<=N){
		c[x]+=y;
		x+=x&-x;
	}
}
int ask(int x){
	int y=0;
	while(x){
		y+=c[x];
		x-=x&-x;
	}
	return y;
}
int used[M];
int main(){
	cin>>n;
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	cin>>m;
	for(int i=1;i<=m;i++){
		scanf("%d%d",&q[i].l,&q[i].r);
		q[i].id=i;
	}
	sort(q+1,q+1+m,cmp);
	int now=1;
	for(int i=1;i<=m;i++){
		for(int j=now;j<=q[i].r;j++){
			if(!used[a[j]]){
				add(j,1);
				used[a[j]]=j;
			}
			else {
				add(used[a[j]],-1);//必须减去之前的贡献再加上之后的贡献,否则在计算时会抵消。
				add(j,1);
				used[a[j]]=j;
			}
		}
		now=q[i].r+1;
		q[i].ans=ask(q[i].r)-ask(q[i].l-1);
	}
	sort(q+1,q+1+m,cmpp);
	for(int i=1;i<=m;i++)
		printf("%d\n",q[i].ans);
	return 0;
}

  

上一篇:kAudioSessionProperty_AudioCategory 的设置


下一篇:MySQL(进阶部分)