421. HH的項鏈
http://218.28.19.228/cogs/problem/problem.php?pid=421
★★★ 輸入文件: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。
/*其實和上個題一樣啦,就是update換了換,記不同的個數*/ #include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int ans,block,n,m,c[50010],s[1000010],pos[50010]; struct node{ int l,r,id,as; }a[200010]; int cmp1(node x,node y){ if(pos[x.l]==pos[y.l])return x.r<y.r; return x.l<y.l; } int cmp2(node x,node y){ return x.id<y.id; } void update(int i,int add){ if(s[c[i]]==0&&add==1)ans++; if(s[c[i]]==1&&add==-1)ans--; s[c[i]]+=add; } void solve(){ int l=1,r=0; for(int i=1;i<=m;i++){ while(r<a[i].r) r++,update(r,1); while(r>a[i].r) update(r,-1),r--; while(l>a[i].l) l--,update(l,1); while(l<a[i].l) update(l,-1),l++; a[i].as=ans; } } int main(){ //freopen("cola.txt","r",stdin); freopen("diff.in","r",stdin); freopen("diff.out","w",stdout); scanf("%d",&n);block=(int)(sqrt(n)); for(int i=1;i<=n;i++)pos[i]=(i-1)/block+1; for(int i=1;i<=n;i++)scanf("%d",&c[i]); scanf("%d",&m); for(int i=1;i<=m;i++)scanf("%d%d",&a[i].l,&a[i].r),a[i].id=i; sort(a+1,a+m+1,cmp1); solve(); sort(a+1,a+m+1,cmp2); for(int i=1;i<=m;i++)printf("%d\n",a[i].as); }