【BZOJ3236】【Ahoi2013】作业

题意:询问区间[L,R]内数值范围在[a,b]的数的个数 以及数值的个数。

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3236

 

写的莫队+树状数组QwQ(其实这是我第一次写莫队2333

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <iostream>
 5 #include <algorithm>
 6 #define MaxN 100010
 7 #define MaxM 1000010
 8 using namespace std;
 9 int n, m, sz;
10 int da[MaxN], ans1[MaxM], ans2[MaxM], cnt[MaxN], p[2][MaxN], pos[MaxN];
11 struct rec{
12     int l, r, a, b, pos;
13 }q[MaxM];
14 
15 int read(){
16     int ret = 0; char c = getchar();
17     while (c < '0' || c > '9') c = getchar();
18     while (c >= '0' && c <= '9') ret = ret*10 + c-'0', c = getchar();
19     return ret;
20 }
21 
22 bool cmp(rec a, rec b){
23     if (pos[a.l] == pos[b.l]) return a.r < b.r;
24     return pos[a.l] < pos[b.l];
25 }
26 
27 int lowbit(int x){ return x&(-x); }
28 
29 int query(int x, int t){
30     int ret = 0;
31     for (int i = x; i; i -= lowbit(i)){
32         ret += p[t][i];
33     }
34     return ret;
35 }
36 
37 void updata(int x, int t, int c){
38     for (int i = x; i <= n; i += lowbit(i)){
39         p[t][i] += c;    
40     }
41 }
42 
43 void updata(int x, int k){
44     if (!cnt[x]) updata(x, 1, 1);
45     cnt[x] += k;
46     if (!cnt[x]) updata(x, 1, -1);
47     updata(x, 0, k);    
48 }
49 
50 int main(){
51     freopen("bzoj3626.in", "r", stdin);
52     freopen("bzoj3626.out", "w", stdout);
53     scanf("%d%d", &n, &m);
54     sz = (int) sqrt(n);
55     for (int i = 1; i <= n; i++) da[i] = read(), pos[i] = i/sz;
56     for (int i = 1; i <= m; i++){
57         q[i].l = read(); q[i].r = read();
58         q[i].a = read(); q[i].b = read();
59         q[i].pos = i;
60     }
61     sort(q+1, q+1+m, cmp);
62     int l = 1, r = 0;
63     for (int i = 1; i <= m; i++){
64         rec now = q[i];
65         while (l < now.l) updata(da[l++], -1);
66         while (l > now.l) updata(da[--l], 1);
67         while (r < now.r) updata(da[++r], 1);
68         while (r > now.r) updata(da[r--], -1);
69         ans1[now.pos] = query(now.b, 0) - query(now.a-1, 0);
70         ans2[now.pos] = query(now.b, 1) - query(now.a-1, 1);
71     }
72     for (int i = 1; i <= m; i++){
73         printf("%d %d\n", ans1[i], ans2[i]);
74     }
75     return 0;
76 }
_(:з」∠)_

 

posted @ 2016-03-08 15:41  Lukaluka  阅读(368)  评论(0编辑  收藏  举报