1. 程式人生 > >洛谷 P1972 [SDOI2009]HH的項鏈

洛谷 P1972 [SDOI2009]HH的項鏈

兩個 data div 莫隊 blog int pac hellip color

P1972 [SDOI2009]HH的項鏈

題目背景

題目描述

HH 有一串由各種漂亮的貝殼組成的項鏈。HH 相信不同的貝殼會帶來好運,所以每次散步完後,他都會隨意取出一段貝殼,思考它們所表達的含義。HH 不斷地收集新的貝殼,因此,他的項鏈變得越來越長。有一天,他突然提出了一個問題:某一段貝殼中,包含了多少種不同的貝殼?這個問題很難回答……因為項鏈實在是太長了。於是,他只好求助睿智的你,來解決這個問題。

輸入輸出格式

輸入格式:

第一行:一個整數N,表示項鏈的長度。

第二行:N 個整數,表示依次表示項鏈中貝殼的編號(編號為0 到1000000 之間的整數)。

第三行:一個整數M,表示HH 詢問的個數。

接下來M 行:每行兩個整數,L 和R(1 ≤ L ≤ R ≤ N),表示詢問的區間。

輸出格式:

M 行,每行一個整數,依次表示詢問對應的答案。

輸入輸出樣例

輸入樣例#1:
6
1 2 3 4 3 5
3
1 2
3 5
2 6
輸出樣例#1:
2
2
4

說明

數據範圍:

對於100%的數據,N <= 50000,M <= 200000。

思路:莫隊。

洛谷:AC。cogs:WA+TLE,數組開小了。

#include<cmath>
#include
<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 50001 #define M 200001 #define MAXN 1000001 using namespace std; int n,m,S,ans; int num[N],sum[MAXN]; struct nond{ int l,r,id,pos,ans; }edge[M]; int cmp1(nond a,nond b){ return a.id<b.id; }
int cmp(nond a,nond b){ if(a.pos==b.pos) return a.r<b.r; else return a.pos<b.pos; } void up(int x,int k){ if(k==1&&!sum[num[x]]) ans++; if(k==-1&&sum[num[x]]==1) ans--; sum[num[x]]+=k; } void mode(){ int l=1,r=0; for(int i=1;i<=m;i++){ while(l<edge[i].l) up(l++,-1); while(l>edge[i].l) up(--l,1); while(r<edge[i].r) up(++r,1); while(r>edge[i].r) up(r--,-1); edge[i].ans=ans; } } int main(){ freopen("diff.in","r",stdin); freopen("diff.out","w",stdout); scanf("%d",&n); S=sqrt(n); for(int i=1;i<=n;i++) scanf("%d",&num[i]); scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%d%d",&edge[i].l,&edge[i].r); edge[i].id=i; edge[i].pos=(edge[i].l-1)/S+1; } sort(edge+1,edge+1+m,cmp); mode(); sort(edge+1,edge+1+m,cmp1); for(int i=1;i<=m;i++) cout<<edge[i].ans<<endl; }

洛谷 P1972 [SDOI2009]HH的項鏈