树状数组--P1972 [SDOI2009]HH的项链
作者:互联网
题目描述
HH 有一串由各种漂亮的贝壳组成的项链。HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义。HH 不断地收集新的贝壳,因此,他的项链变得越来越长。
有一天,他突然提出了一个问题:某一段贝壳中,包含了多少种不同的贝壳?这个问题很难回答…… 因为项链实在是太长了。于是,他只好求助睿智的你,来解决这个问题。
输入格式
一行一个正整数 n,表示项链长度。
第二行 n 个正整数 ai,表示项链中第 iii 个贝壳的种类。
第三行一个整数 m,表示 HH 询问的个数。
接下来 m 行,每行两个整数 l,r,表示询问的区间。
输出格式
输出 m 行,每行一个整数,依次表示询问对应的答案。
1.按r排序一下
2.树状数组tree[j]维护从1到j不同数字的个数有多少个
3.然后用前缀和思想(tree[r]-tree[l-1])
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 #define maxn 1000009 7 int num[maxn],tree[maxn],flag[maxn],tmp[maxn],N,w; 8 using namespace std; 9 inline int read() 10 { 11 int x = 1,a = 0; 12 char ch = getchar(); 13 while(ch < '0' || ch > '9'){ 14 if(ch == '-')x = -1; 15 ch = getchar(); 16 } 17 while(ch <= '9'&&ch >= '0'){ 18 a = a * 10 + ch - '0'; 19 ch = getchar(); 20 } 21 return x*a; 22 } 23 struct node 24 { 25 int l,r; 26 int pos; 27 }; 28 node ask[maxn]; 29 inline bool cmp(node x,node y) 30 { 31 return x.r<y.r; 32 } 33 inline void add(int n,int now) 34 { 35 for (register int i = n;i <= N;i+=i&(-i)) 36 { 37 tree[i]+=now; 38 } 39 } 40 inline int sum(int n) 41 { 42 int ans=0; 43 for (register int i = n;i;i-=i&(-i)) 44 { 45 ans+=tree[i]; 46 } 47 return ans; 48 } 49 int main() 50 { 51 N=read(); 52 for(register int i=1;i<=N;i++) 53 num[i]=read(); 54 w=read(); 55 for(register int i=1;i<=w;i++) 56 { 57 ask[i].l=read(); 58 ask[i].r=read(); 59 ask[i].pos=i; 60 } 61 sort(ask+1,ask+1+w,cmp); 62 int next=1; 63 for(register int i=1;i<=w;i++) 64 { 65 for(register int j=next;j<=ask[i].r;j++) 66 { 67 if(flag[num[j]]) 68 add(flag[num[j]],-1); 69 add(j,1); 70 flag[num[j]]=j; 71 } 72 next=ask[i].r+1; 73 tmp[ask[i].pos]=sum(ask[i].r)-sum(ask[i].l-1); 74 } 75 for(register int i=1;i<=w;i++) 76 cout<<tmp[i]<<endl; 77 return 0; 78 }
标签:ch,贝壳,int,HH,maxn,项链,SDOI2009,P1972 来源: https://www.cnblogs.com/very-beginning/p/12248758.html