P1972 [SDOI2009]HH的项链

H y p e r l i n k Hyperlink Hyperlink

https://www.luogu.org/problemnew/show/P1972


D e s c r i p t i o n Description Description

一个长度为 n n n的序列,第 i i i个序列数字为 a i a_i ai。给定 m m m组询问,每次询问 [ l i , r i ] [l_i,r_i] [li,ri]区间内不同的数字个数

数据范围: n , m ≤ 5 × 1 0 5 , a i ≤ 1 0 6 n,m\leq 5\times 10^5,a_i\leq 10^6 n,m5×105,ai106


S o l u t i o n Solution Solution

这题明显就是这道题的不用离散化(或者 h a s h , m a p hash,map hash,map+卡常)的版本嘛2333

莫队即可


C o d e Code Code

#include
#include
#include
#include
#define N 500010
using namespace std;
inline long long read()
{
    char c;int f=0,d=1;
    while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
    while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
    return d*f;
}
int belong[N],cnt[1000010],a[N],t,n,ans[N],now;
struct node
{
	int l,r,id;
	bool operator<(const node&x) const{return belong[l]^belong[x.l]?l<x.l:belong[x.l]&1?r<x.r:r>x.r;}
}q[N];
inline void add(int x){if(++cnt[x]==1) now++;return;}
inline void del(int x){if(--cnt[x]==0) now--;return;}
inline void write(int x){if(x>9) write(x/10);putchar(x%10+48);return;}
signed main()
{
	n=read();
	t=1250;
	for(register int i=1;i<=n;++i) a[i]=read(),belong[i]=(i-1)/t+1;
	int Q=read();
	for(register int i=1;i<=Q;++i) q[i].l=read(),q[i].r=read(),q[i].id=i;
	sort(q+1,q+1+Q);
	for(register int i=1,l=1,r=0;i<=Q;++i)
	{
		while(l<q[i].l) del(a[l++]);
		while(q[i].l<l) add(a[--l]);
		while(r<q[i].r) add(a[++r]);
		while(q[i].r<r) del(a[r--]);
		ans[q[i].id]=now;
	}
	for(register int i=1;i<=Q;i++) write(ans[i]),putchar(10);
}

你可能感兴趣的:(莫队,分块)