[BZOJ2743] [HEOI2012] 采花 (樹狀數組)


Description

  蕭芸斕是Z國的公主,平時的一大愛好是采花。
  今天天氣晴朗,陽光明媚,公主清晨便去了皇宮中新建的花園采花。花園足夠大,容納了n朵花,花有c種顏色(用整數1-c表示),且花是排成一排的,以便於公主采花。公主每次采花后會統計采到的花的顏色數,顏色數越多她會越高興!同時,她有一癖好,她不允許最后自己采到的花中,某一顏色的花只有一朵。為此,公主每采一朵花,要么此前已采到此顏色的花,要么有相當正確的直覺告訴她,她必能再次采到此顏色的花。由於時間關系,公主只能走過花園連續的一段進行采花,便讓女仆福涵潔安排行程。福涵潔綜合各種因素擬定了m個行程,然后一一向你詢問公主能采到多少朵花(她知道你是編程高手,定能快速給出答案!),最后會選擇令公主最高興的行程(為了拿到更多獎金!)。

Input 

  第一行四個空格隔開的整數n、c以及m。接下來一行n個空格隔開的整數,每個數在[1, c]間,第i個數表示第i朵花的顏色。接下來m行每行兩個空格隔開的整數l和r(l ≤ r),表示女仆安排的行程為公主經過第l到第r朵花進行采花。

Output 

  共m行,每行一個整數,第i個數表示公主在女仆的第i個行程中能采到的花的顏色數。

Sample Input

5 3 5
1 2 2 3 1
1 5
1 2
2 2
2 3
3 5

Sample Output

2
0 0 1 0

  【樣例說明】
  詢問[1, 5]:公主采顏色為1和2的花,由於顏色3的花只有一朵,公主不采;詢問[1, 2]:顏色1和顏色2的花均只有一朵,公主不采;
  詢問[2, 2]:顏色2的花只有一朵,公主不采;
  詢問[2, 3]:由於顏色2的花有兩朵,公主采顏色2的花;
  詢問[3, 5]:顏色1、2、3的花各一朵,公主不采。

HINT

  對於100%的數據,1 ≤ n ≤ 10^6,c ≤ n,m ≤10^6。

Source

Solution

  HH的項鏈即視感,保證該顏色第二次在區間內出現時答案+1即可

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN = 1000005;
 4 struct query
 5 {
 6     int id, l, r;
 7     bool operator < (const query &rhs) const
 8     {
 9         return l == rhs.l ? r < rhs.r : l < rhs.l;
10     }
11 }q[MAXN];
12 int n, a[MAXN], fst[MAXN], nxt[MAXN], BIT[MAXN], ans[MAXN];
13 
14 void update(int x, int val)
15 {
16     for(; x <= n; x += x & -x)
17         BIT[x] += val;
18 }
19 
20 int query(int x)
21 {
22     int ans = 0;
23     for(; x; x -= x & -x)
24         ans += BIT[x];
25     return ans;
26 }
27 
28 int main()
29 {
30     int m, l = 0, c;
31     scanf("%d%d%d", &n, &c, &m);
32     for(int i = 1; i <= n; i++)
33         scanf("%d", a + i);
34     for(int i = n; i; i--)
35         nxt[i] = fst[a[i]], fst[a[i]] = i;
36     for(int i = 0; i <= c; i++)
37         if(nxt[fst[i]]) update(nxt[fst[i]], 1);
38     for(int i = 1; i <= m; i++)
39         scanf("%d%d", &q[i].l, &q[i].r), q[i].id = i;
40     sort(q + 1, q + m + 1);
41     for(int i = 1; i <= m; i++)
42     {
43         while(l < q[i].l - 1)
44         {
45             if(nxt[++l]) update(nxt[l], -1);
46             if(nxt[nxt[l]]) update(nxt[nxt[l]], 1);
47         }
48         ans[q[i].id] = query(q[i].r) - query(q[i].l - 1);
49     }
50     for(int i = 1; i <= m; i++)
51         printf("%d\n", ans[i]);
52     return 0;
53 }
View Code

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: