树状数组--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 }

 

 
上一篇:时间换算 (10分)(C语言)


下一篇:map基础知识与常用函数