★★★ 輸入文件:diff.in
輸出文件:diff.out
簡單對比
時間限制:1 s 內存限制:256 MB
問題描述:
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。
調了1h竟然是數組開小了:
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; const int N=2000100; int a[N],pos[N],number[N],answer[N]; bool vis[N]; int n,m,ans; struct node{ int l,r,num; }E[N<<2]; inline int read() { int x=0;char c=getchar();int f=1; while(c<'0'||c>'9'){if(f=='-')f=-1;c=getchar(); } while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar(); return x; } bool cmp(node a,node b) { if(pos[a.l]==pos[b.l]) return a.r<b.r; else return pos[a.l]<pos[b.l]; } int add(int x) { number[x]++; if(number[x]==1) ans++; } int dale(int x) { number[x]--; if(number[x]==0) ans--; } int MD() { int ll=1,rr=0; for(int i=1;i<=m;i++) { for(;E[i].l<ll;ll--)add(a[ll-1]); for(;E[i].l>ll;ll++)dale(a[ll]); for(;E[i].r>rr;rr++)add(a[rr+1]); for(;E[i].r<rr;rr--)dale(a[rr]); answer[E[i].num]=ans; } } int main() { freopen("diff.in","r",stdin); freopen("diff.out","w",stdout); n=read(); for(int i=1;i<=n;i++) a[i]=read(); m=read(); for(int i=1;i<=m;i++) {E[i].l=read();E[i].r=read();E[i].num=i;} int base=sqrt(n); for(int i=1;i<=n;i++) pos[i]=(i-1)/base+1; sort(E+1,E+m+1,cmp); MD(); for(int i=1;i<=m;i++) printf("%d\n",answer[i]); return 0; } /* 6 1 2 3 4 3 5 3 1 2 3 5 2 6 */