D-query
Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query is a pair (i, j) (1 ≤ i ≤ j ≤ n). For each d-query (i, j), you have to return the number of distinct elements in the subsequence ai, ai+1, ..., aj.
Input
- Line 1: n (1 ≤ n ≤ 30000).
- Line 2: n numbers a1, a2, ..., an (1 ≤ ai ≤ 106).
- Line 3: q (1 ≤ q ≤ 200000), the number of d-queries.
- In the next q lines, each line contains 2 numbers i, j representing a d-query (1 ≤ i ≤ j ≤ n).
Output
- For each d-query (i, j), print the number of distinct elements in the subsequence ai, ai+1, ..., aj in a single line.
Example
Input 5 1 1 2 1 3 3 1 5 2 4 3 5 Output 3 2 3
题意:求区间内不重复的数的个数。 n,m<=100000
题解:建立可持久化线段树,以右端点为最后建立现在版本线段树,
然后就是维护每一棵线段树,就是前面的点什么时候失效,询问大区间就一定会包含小区间中的
相同权值的点,然后只需要记录和即可,离散化还是需要的+二分。
1 #include<cstring> 2 #include<cmath> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdio> 6 7 #define N 60007 8 #define M 20000007 9 using namespace std; 10 inline int read() 11 { 12 int x=0,f=1;char ch=getchar(); 13 while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();} 14 while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 18 int n,top,sz,q; 19 int a[N],b[N],num[N],pos[N],root[N]; 20 int ls[M],rs[M],sum[M]; 21 22 int bs(int num) 23 { 24 int l=1,r=top; 25 while(l<=r) 26 { 27 int mid=(l+r)>>1; 28 if (b[mid]==num) return mid; 29 if (b[mid]<num) l=mid+1; 30 else r=mid-1; 31 } 32 } 33 void change(int l,int r,int x,int &y,int wei,int z) 34 { 35 y=++sz; 36 if (l==r) 37 { 38 sum[y]=sum[x]+z; 39 return; 40 } 41 ls[y]=ls[x],rs[y]=rs[x],sum[y]=sum[x]+z; 42 int mid=(l+r)>>1; 43 if (wei<=mid) change(l,mid,ls[x],ls[y],wei,z); 44 else change(mid+1,r,rs[x],rs[y],wei,z); 45 } 46 47 int query(int p,int l,int r,int x,int y) 48 { 49 if (l==x&&y==r) return sum[p]; 50 int mid=(l+r)>>1; 51 if (y<=mid) return query(ls[p],l,mid,x,y); 52 else if (x>mid) return query(rs[p],mid+1,r,x,y); 53 else return query(ls[p],l,mid,x,mid)+query(rs[p],mid+1,r,mid+1,y); 54 } 55 int main() 56 { 57 int n=read(); 58 for (int i=1;i<=n;i++) 59 a[i]=read(),b[i]=a[i]; 60 sort(b+1,b+n+1); 61 top=1; 62 for (int i=2;i<=n;i++) 63 if (b[i]!=b[i-1]) b[++top]=b[i]; 64 for (int i=1;i<=n;i++) 65 { 66 int num=bs(a[i]); 67 change(1,n,root[i-1],root[i],i,1); 68 if (pos[num]) change(1,n,root[i],root[i],pos[num],-1); 69 pos[num]=i; 70 } 71 q=read(); 72 while(q--) 73 { 74 int l=read(),r=read(); 75 printf("%d\n",query(root[r],1,n,l,r)); 76 } 77 }