链接:https://www.nowcoder.com/acm/contest/139/J
来源:牛客网
时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
Given a sequence of integers a
1, a
2, ..., a
n and q pairs of integers (l
1, r
1), (l
2, r
2), ..., (l
q, r
q), find count(l
1, r
1), count(l
2, r
2), ..., count(l
q, r
q) where count(i, j) is the number of different integers among a
1, a
2, ..., a
i, a
j, a
j + 1, ..., a
n.
输入描述:
The input consists of several test cases and is terminated by end-of-file.1
The first line of each test cases contains two integers n and q.
The second line contains n integers a
, a2
, ..., an
.i
The i-th of the following q lines contains two integers l
and ri
.
输出描述:
For each test case, print q integers which denote the result.
备注:
* 1 ≤ n, q ≤ 105
i
* 1 ≤ a
≤ ni
* 1 ≤ l
, ri
≤ n
* The number of test cases does not exceed 10.
骚操作:直接把数组*2 然后求1-L,R-N 就变成 求R-L+N之间的不同数的个数了;注意,主席树会TLE;要用线段数组+离线
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <map> using namespace std; const int maxn=300000+5; map<int,int> mp; int data[maxn]; int a[maxn]; int ans[200000+5]; struct node{ int l,r,id; bool operator<(node t)const{ return r<t.r; } }q[200000+5]; int sum(int i){ int ans=0; while(i>0){ ans+=data[i]; i-=i&-i; } return ans; } void add(int i,int x){ while(i<maxn){ data[i]+=x; i+=i&-i; } } int main() { int n,m; while(~scanf("%d%d",&n,&m)){ fill(data,data+n*2+2,0); mp.clear(); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); a[i+n]=a[i]; } n=n*2; for(int i=0;i<m;i++){ int x,y; scanf("%d%d",&x,&y); q[i].l=y; q[i].r=x+n/2; q[i].id=i; } sort(q,q+m); int pre=1; for(int i=0;i<m;i++){ for(int j=pre;j<=q[i].r;j++){ if(mp[a[j]]!=0){ add(mp[a[j]],-1); } add(j,1); mp[a[j]]=j; } pre=q[i].r+1; ans[q[i].id]=sum(q[i].r)-sum(q[i].l-1); } for(int i=0;i<m;i++){ printf("%d\n",ans[i]); } } return 0; }
也可以莫队加上读入挂
#include<bits/stdc++.h> using namespace std; int n,q,a[100005]; int L,R,ans; struct node{ int l,r,id; }; node temp[100005]; int sum[1000005]; int anw[1000005]; int block[100005]; int read() { char ch=' '; int ans=0; while(ch<'0' || ch>'9') ch=getchar(); while(ch<='9' && ch>='0') { ans=ans*10+ch-'0'; ch=getchar(); } return ans; } int cmp(node a,node b){ if(block[a.l]==block[b.l])return block[a.r]<block[b.r]; return block[a.l]<block[b.l]; } void add(int x){ if(sum[x]==0)ans++;sum[x]++; } void del(int x){ sum[x]--;if(sum[x]==0)ans--; } int main() { ios::sync_with_stdio(false); while(~scanf("%d%d",&n,&q)){ memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++){ a[i]=read(); block[i]=i/sqrt(n); } for(int i=1;i<=q;i++){ temp[i].l=read(); temp[i].r=read(); temp[i].id=i; } sort(temp+1,temp+1+q,cmp); L=0;R=n+1;ans=0; for(int i=1;i<=q;i++){ while(L<temp[i].l)L++,add(a[L]); while(R>temp[i].r)R--,add(a[R]); while(L>temp[i].l)del(a[L]),L--; while(R<temp[i].r)del(a[R]),R++; anw[temp[i].id]=ans; } for(int i=1;i<=q;i++)printf("%d\n",anw[i]); } return 0; }