Problem Description
https://www.luogu.com.cn/problem/P1972
HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,
因此,他的项链变得越来越长。
有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答…… 因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题
Analysis of ideas
题意就是询问一个区间内,不同的数字有多少个
莫队的精髓就是分块,对于这些区间,给每个区间的右端点分块,同一个块内按区间左端点排序,然后移动双指针来回跳动
莫队的时间复杂度(O(n sqrt n))
莫队的模板
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define pii pair<int,int>
#define int long long
#define ll __int128_t
const int inf = 0x3f3f3f3f;
const int maxn = 1001110;
const int M = 1e9+7;
int n,m;
int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+c-'0',c=getchar();
return f*x;
}
void print(int x)
{
if(x < 0) {putchar('-');x = -x;}
if(x/10) print(x/10);
putchar(x%10+'0');
}
int a[maxn];
int pos[maxn];
int ans[maxn];
int cnt[maxn];
struct node
{
int l,r,id;
bool operator < (const node tmp) const{
if(pos[l] == pos[tmp.l]) return r < tmp.r;
return pos[l] < pos[tmp.l];
}
}q[maxn];
int res;
void del(int x)
{
cnt[x]--;
if(cnt[x] == 0) res--;
}
void add(int x)
{
if(cnt[x] == 0) res++;
cnt[x]++;
}
signed main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
#endif
n = read();
int t = sqrt(n);
for(int i = 1; i <= n; i++)
{
a[i] = read();
pos[i] = i/t;
}
m = read();
for(int i = 1; i <= m; i++)
{
q[i].l = read();q[i].r = read();
q[i].id = i;
}
sort(q+1,q+1+m);
int l = 1,r = 0;
for(int i = 1; i <= m; i++)
{
while(l < q[i].l)
{
del(a[l]);
l++;
}
while(l > q[i].l)
{
l--;
add(a[l]);
}
while(r > q[i].r)
{
del(a[r]);
r--;
}
while(r < q[i].r)
{
r++;
add(a[r]);
}
ans[q[i].id] = res;
}
for(int i = 1; i <= m; i++)
{
print(ans[i]);putchar('
');
}
return 0;
}