1. 题目
题目描述
HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步 完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此, 他的项链变得越来越长。有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同 的贝壳?这个问题很难回答。。。因为项链实在是太长了。于是,他只好求助睿智的你,来解 决这个问题。
输入格式
第一行:一个整数 N,表示项链的长度。 第二行:N 个整数,表示依次表示项链中贝壳的编号(编号为 0 到 1000000 之间的整数)。 第三行:一个整数 M,表示 HH 询问的个数。 接下来 M 行:每行两个整数,L 和 R(1 ≤ L ≤ R ≤ N),表示询问的区间。
输出格式
M 行,每行一个整数,依次表示询问对应的答案。
样例输入
6
1 2 3 4 3 5
3
1 2
3 5
2 6
样例输出
2
2
4
提示
对于 20% 的数据,N ≤ 100,M ≤ 1000; 对于 40% 的数据,N ≤ 3000,M ≤ 200000; 对于 100% 的数据,N ≤ 50000,M ≤ 200000。
题目来源
Day2
题解
明显普通莫队模板题,直接上莫队 1A。
#include <bits/stdc++.h>
using namespace std;
template<typename tp>void read(tp & dig)
{
char c=getchar();dig=0;
while(!isdigit(c))c=getchar();
while(isdigit(c))dig=dig*10+c-'0',c=getchar();
}
struct node{int l,r,i;};
int n,sqn,m,arr[50005],cnt[1000005],l,r,tot,ans[200005];
vector<node> tab;
inline int bi(int a){return (a-1)/sqn+1;}
bool cmp(node a,node b){if(bi(a.l)==bi(b.l))return a.r<b.r;return a.l<b.l;}
int main()
{
read(n),sqn=sqrt(n);
for(int i=1;i<=n;i++)read(arr[i]);
read(m);
for(int i=1,a,b;i<=m;i++)read(a),read(b),tab.push_back((node){a,b,i});
sort(tab.begin(),tab.end(),cmp),l=r=tab[0].l,tot=cnt[arr[l]]=1;
for(int i=0;i<m;i++)
{
for(;l<tab[i].l;l++)if(!--cnt[arr[l]])tot--;
for(--l;l>=tab[i].l;l--)if(!cnt[arr[l]]++)tot++;
for(;r>tab[i].r;r--)if(!--cnt[arr[r]])tot--;
for(++r;r<=tab[i].r;r++)if(!cnt[arr[r]]++)tot++;
ans[tab[i].i]=tot,l=tab[i].l,r=tab[i].r;
}
for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
return 0;
}
0 条评论