Given a sequence of integers a1, a2, ..., an and q pairs of integers (l1, r1), (l2, r2), ..., (lq, rq), find count(l1, r1), count(l2, r2), ..., count(lq, rq) where count(i, j) is the number of different integers among a1, a2, ..., ai, aj, aj + 1, ..., an.
输入描述:
The input consists of several test cases and is terminated by end-of-file. The first line of each test cases contains two integers n and q. The second line contains n integers a1, a2, ..., an. The i-th of the following q lines contains two integers li and ri.
输出描述:
For each test case, print q integers which denote the result.
示例1
输入
复制
3 2 1 2 1 1 2 1 3 4 1 1 2 3 4 1 3
输出
复制
2 1 3
备注:
* 1 ≤ n, q ≤ 105 * 1 ≤ ai ≤ n * 1 ≤ li, ri ≤ n * The number of test cases does not exceed 10.
题意:将1-l和r-n的所有元素放到一个集合中,问集合中有多少元素?
题解:最水的一道题都做了五个小时,而且还理解错题意了,不得不说这真是菜的可以,区域赛的难度对于我来说的确还是有点高了,这道题正解是树状数组,但还是可以用莫队算法卡过去的,复杂度nsqrt(n),可以将区间变成原来的两倍,这样就可以直接用莫队了,莫队的思路较简单,将所要询问的区间保存起来然后排序,用l的大小来进行分块,每pow(q,0.57)分为一块即可。
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<deque>
#include<ctype.h>
#include<map>
#include<set>
#include<stack>
#include<string>
#include<algorithm>
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define FAST_IO ios::sync_with_stdio(false)
#define mem(a,b) memset(a,b,sizeof(a))
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAX=1e6+10;
const long long INF=0x7FFFFFFFFFFFFFFFLL;
const int inf=0x3f3f3f3f;
typedef long long ll;
using namespace std;
const long long mod=1e9+7;
inline ll read(){ll x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;}
int cnt[1000005],a[2000005],ans,block;
struct node
{
int l,r,num,ans;
}p[1000005];
inline void add(int x)
{
int xx=a[x];
cnt[xx]++;
if(cnt[xx]==1) ans++;
}
inline void rem(int x)
{
int xx=a[x];
cnt[xx]--;
if(cnt[xx]==0) ans--;
}
int cmp(node a,node b)
{
if((a.l/block)!=(b.l/block))
return a.l<b.l;
return a.r<b.r;
}
int cmp2(node a,node b)
{
return a.num<b.num;
}
int main()
{
int n,q;
while(scanf("%d%d",&n,&q)!=EOF)
{
mem(cnt,0);
mem(p,0);
block=(int)pow(q,0.57);
for(int i=1;i<=n;i++){
a[i]=read();
a[n+i]=a[i];
}
for(int i=1;i<=q;i++)
{
p[i].l=read();
p[i].r=read();
int tmp=p[i].r;
p[i].r=p[i].l+n;
p[i].l=tmp;
p[i].num=i;
}
sort(p+1,p+1+q,cmp);
ans=0;
int left=1,right=1; add(1);
for(int i=1;i<=q;i++)
{
while(left<p[i].l) {rem(left);left++;}
while(left>p[i].l) {left--;add(left);}
while(right<p[i].r) {right++;add(right);}
while(right>p[i].r) {rem(right);right--;}
p[i].ans=ans;
}
sort(p+1,p+1+q,cmp2);
for(int i=1;i<=q;i++)
printf("%d\n",p[i].ans);
}
return 0;
}