Loading

BZOJ 1878:[SDOI2009]HH的项链(莫队算法)

http://www.lydsy.com/JudgeOnline/problem.php?id=1878

题意:……

思路:比上题还简单很多。数字很小,开一个数组哈希记录出现次数(记得数组要开1e6),然后直接算就行了。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 #define N 50010
 7 struct node {
 8     int l, r, ans, id;
 9 } p[N*4];
10 int mp[N*20], num[N], ans, kuai;
11 
12 bool cmp(const node &a, const node &b) {
13     if(a.l / kuai == b.l / kuai) return a.r < b.r;
14     return a.l / kuai < b.l / kuai;
15 }
16 
17 bool cmpid(const node &a, const node &b) {
18     return a.id < b.id;
19 }
20 
21 void update(int id, int w) {
22     if(mp[num[id]]) ans--; mp[num[id]] += w; if(mp[num[id]]) ans++;
23 }
24 
25 int main() {
26     int n, m;
27     while(~scanf("%d", &n)) {
28         for(int i = 1; i <= n; i++) scanf("%d", num + i);
29         scanf("%d", &m);
30         for(int i = 1; i <= m; i++) scanf("%d%d", &p[i].l, &p[i].r), p[i].id = i;
31         kuai = sqrt(n); ans = 0;
32         memset(mp, 0, sizeof(mp));
33         sort(p + 1, p + 1 + m, cmp);
34         for(int L = 1, R = 0, i = 1; i <= m; i++) {
35             int l = p[i].l, r = p[i].r;
36             for( ; L < l; L++) update(L, -1);
37             for( ; L > l; L--) update(L - 1, 1);
38             for( ; R < r; R++) update(R + 1, 1);
39             for( ; R > r; R--) update(R, -1);
40             p[i].ans = ans;
41         }
42         sort(p + 1, p + 1 + m, cmpid);
43         for(int i = 1; i <= m; i++) printf("%d\n", p[i].ans);
44     }
45     return 0;
46 }
47 /*
48 6
49 1 2 3 4 3 5
50 4
51 1 2
52 3 5
53 2 6
54 1 1
55 */

 

posted @ 2017-01-25 19:56  Shadowdsp  阅读(182)  评论(0编辑  收藏  举报