NKOJ P2387 「NOIP模拟」 赏花【莫队板子】

这道题在没学莫队之前用树状数组和线段树写了好久…然而莫队直接秒杀树状数组线段树做法…

参考代码:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define SG string
#define DB double
using namespace std;
const int Max1=2e5+5;
const int Max2=1e5+5;
struct Node{
	int X,Y,Id;
}Ask[Max1];
int N,M,S,Num,A[Max2],B[Max2],Cnt[Max2],Ans[Max1];
inline int Read(){
	int X=0;char CH=getchar();bool F=0;
	while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
	while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
	return F?-X:X;
}
inline void Write(int X){
	if(X<0)X=-X,putchar('-');
	if(X>9)Write(X/10);
	putchar(X%10+48);
}
void Insert(int X){
	if(!Cnt[A[X]]){
		Num++;
	}Cnt[A[X]]++;
}
void Delete(int X){
	if(Cnt[A[X]]==1){
		Num--;
	}Cnt[A[X]]--;
}
bool Cmp(Node P,Node Q){
	return B[P.X]==B[Q.X]?P.Y<Q.Y:B[P.X]<B[Q.X];
}
int main(){
	int I,J,K;
	N=Read();S=sqrt(N);
	for(I=1;I<=N;I++){
		A[I]=Read();B[I]=I/S;
	}
	M=Read();
	for(I=1;I<=M;I++){
		Ask[I].Id=I;
		Ask[I].X=Read();
		Ask[I].Y=Read();
	}
	sort(Ask+1,Ask+1+M,Cmp);
	int Left=1,Right=1;Insert(1);
	for(I=1;I<=M;I++){
		while(Right<Ask[I].Y){
			Insert(++Right);
		}
		while(Right>Ask[I].Y){
			Delete(Right--);
		}
		while(Left<Ask[I].X){
			Delete(Left++);
		}
		while(Left>Ask[I].X){
			Insert(--Left);
		}
		Ans[Ask[I].Id]=Num;
	}
	for(I=1;I<=M;I++){
		Write(Ans[I]),putchar('\n');
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值