3236: [Ahoi2013]作业
Time Limit: 100 Sec Memory Limit: 512 MBSubmit: 1393 Solved: 562
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
3 4
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3
1 2 2
1 2 1 3
1 2 1 1
1 3 1 3
2 3 2 3
Sample Output
2 2
1 1
3 2
2 1
1 1
3 2
2 1
HINT
N=100000,M=1000000
Source
莫队算法 + 树状数组统计答案
1 #include <cmath> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 8 using namespace std; 9 10 /* SCANNER */ 11 12 #define siz 10000000 13 14 inline char get_a(void) { 15 static char buf[siz], *bit = buf; 16 17 if (bit == buf + siz) 18 fread(bit = buf, 1, siz, stdin); 19 20 return *bit++; 21 } 22 23 inline int get_i(void) { 24 register int ret = 0; 25 register int neg = false; 26 register int bit = get_a(); 27 28 for (; bit < '0'; bit = get_a()) 29 if (bit == '-')neg ^= true; 30 31 for (; bit >= '0'; bit = get_a()) 32 ret = ret * 10 + bit - '0'; 33 34 return neg ? -ret : ret; 35 } 36 37 #define maxn 400005 38 #define maxm 1000005 39 40 int s; 41 int tot; 42 int n, m; 43 int num[maxn]; 44 int cnt[maxn]; 45 int tmp[maxn]; 46 int ans1[maxm]; 47 int ans2[maxm]; 48 int tree1[maxn]; 49 int tree2[maxn]; 50 51 struct query { 52 int l, r, a, b, id; 53 }qry[maxm]; 54 55 inline int cmp(const void *a, const void *b) { 56 query *A = (query *)a; 57 query *B = (query *)b; 58 if (A->l / s != B->l / s) 59 return A->l - B->l; 60 else 61 return A->r - B->r; 62 } 63 64 inline void add(int *t, int p, int k) { 65 for (; p <= tot; p += p&-p) 66 t[p] += k; 67 } 68 69 inline int ask(int *t, int p) { 70 int ret = 0; 71 for (; p; p -= p&-p) 72 ret += t[p]; 73 return ret; 74 } 75 76 inline void remove(int t) { 77 add(tree1, t, -1); 78 if (--cnt[t] == 0) 79 add(tree2, t, -1); 80 } 81 82 inline void insert(int t) { 83 add(tree1, t, 1); 84 if (++cnt[t] == 1) 85 add(tree2, t, 1); 86 } 87 88 signed main(void) { 89 n = get_i(); 90 m = get_i(); 91 s = sqrt(n); 92 93 for (int i = 1; i <= n; ++i) 94 num[i] = get_i(), tmp[++tot] = num[i]; 95 96 for (int i = 1; i <= m; ++i) { 97 qry[i].id = i; 98 qry[i].l = get_i(); 99 qry[i].r = get_i(); 100 qry[i].a = get_i(); 101 qry[i].b = get_i(); 102 } 103 104 for (int i = 1; i <= m; ++i) 105 tmp[++tot] = qry[i].a, 106 tmp[++tot] = qry[i].b; 107 108 sort(tmp + 1, tmp + 1 + tot); 109 110 tot = unique(tmp + 1, tmp + 1 + tot) - tmp; 111 112 for (int i = 1; i <= n; ++i) 113 num[i] = lower_bound(tmp + 1, tmp + tot, num[i]) - tmp; 114 115 for (int i = 1; i <= m; ++i) { 116 qry[i].a = lower_bound(tmp + 1, tmp + tot, qry[i].a) - tmp; 117 qry[i].b = lower_bound(tmp + 1, tmp + tot, qry[i].b) - tmp; 118 } 119 120 /* 121 for (int i = 1; i <= n; ++i) 122 printf("%d ", num[i]); 123 124 puts(""); 125 126 for (int i = 1; i <= m; ++i) 127 printf("%d %d ", qry[i].a, qry[i].b); 128 */ 129 130 qsort(qry + 1, m, sizeof(query), cmp); 131 132 int l = 1, r = 0; 133 134 for (int i = 1; i <= m; ++i) { 135 while (l < qry[i].l)remove(num[l++]); 136 while (l > qry[i].l)insert(num[--l]); 137 while (r < qry[i].r)insert(num[++r]); 138 while (r > qry[i].r)remove(num[r--]); 139 ans1[qry[i].id] = ask(tree1, qry[i].b) - ask(tree1, qry[i].a - 1); 140 ans2[qry[i].id] = ask(tree2, qry[i].b) - ask(tree2, qry[i].a - 1); 141 } 142 143 for (int i = 1; i <= m; ++i) 144 printf("%d %d ", ans1[i], ans2[i]); 145 146 //system("pause"); 147 }
1 #include <cmath> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 8 using namespace std; 9 10 /* SCANNER */ 11 12 #define siz 50000000 13 14 inline int get_c(void) 15 { 16 static char buf[siz]; 17 static char *head = buf; 18 static char *tail = buf + siz; 19 20 if (head == tail) 21 fread(head = buf, 1, siz, stdin); 22 23 return *head++; 24 } 25 26 #define getc get_c 27 // #define getc getchar 28 29 inline int get_i(void) 30 { 31 register int ret = 0; 32 register int neg = false; 33 register int bit = getc(); 34 35 for (; bit < '0'; bit = getc()) 36 if (bit == '-')neg ^= true; 37 38 for (; bit >= '0'; bit = getc()) 39 ret = ret * 10 + bit - '0'; 40 41 return neg ? -ret : ret; 42 } 43 44 /* PROBLEM */ 45 46 #define maxn 100005 47 #define maxm 1000005 48 49 int n, m, s; 50 int num[maxn]; 51 int cnt[maxm * 3]; 52 int tmp[maxm * 3]; 53 int *tot = tmp + 1; 54 int tree1[maxm * 3]; 55 int tree2[maxm * 3]; 56 57 /* QRY */ 58 59 struct query 60 { 61 int l, r; 62 int a, b; 63 int ans1; 64 int ans2; 65 }qry[maxm], *ord[maxm]; 66 67 inline bool cmp(query *a, query *b) 68 { 69 if (a->l / s != b->l / s) 70 return a->l < b->l; 71 else 72 return a->r < b->r; 73 } 74 75 /* BIT */ 76 77 inline void add(int *t, int p, int k) 78 { 79 int len = tot - tmp; 80 for (; p <= len; p += p&-p) 81 t[p] += k; 82 } 83 84 inline int ask(int *t, int p) 85 { 86 int ret = 0; 87 for (; p; p -= p&-p) 88 ret += t[p]; 89 return ret; 90 } 91 92 /* MOQ */ 93 94 inline void insert(int t) 95 { 96 add(tree1, t, +1); 97 if (++cnt[t] == 1) 98 add(tree2, t, +1); 99 } 100 101 inline void remove(int t) 102 { 103 add(tree1, t, -1); 104 if (--cnt[t] == 0) 105 add(tree2, t, -1); 106 } 107 108 /* MAIN */ 109 110 signed main(void) 111 { 112 n = get_i(); 113 m = get_i(); 114 s = sqrt(n); 115 116 for (int i = 1; i <= n; ++i) 117 *tot++ = num[i] = get_i(); 118 119 for (int i = 1; i <= m; ++i) 120 { 121 ord[i] = qry + i; 122 qry[i].l = get_i(); 123 qry[i].r = get_i(); 124 *tot++ = qry[i].a = get_i(); 125 *tot++ = qry[i].b = get_i(); 126 } 127 128 sort(tmp + 1, tot); 129 130 tot = unique(tmp + 1, tot); 131 132 for (int i = 1; i <= n; ++i) 133 num[i] = lower_bound(tmp + 1, tot, num[i]) - tmp; 134 135 for (int i = 1; i <= m; ++i) 136 { 137 qry[i].a = lower_bound(tmp + 1, tot, qry[i].a) - tmp; 138 qry[i].b = lower_bound(tmp + 1, tot, qry[i].b) - tmp; 139 } 140 141 sort(ord + 1, ord + 1 + m, cmp); 142 143 int lt = 1, rt = 0; // left & right 144 145 for (int i = 1; i <= m; ++i) 146 { 147 query *q = ord[i]; 148 while (lt < q->l)remove(num[lt++]); 149 while (lt > q->l)insert(num[--lt]); 150 while (rt < q->r)insert(num[++rt]); 151 while (rt > q->r)remove(num[rt--]); 152 q->ans1 = ask(tree1, q->b) - ask(tree1, q->a - 1); 153 q->ans2 = ask(tree2, q->b) - ask(tree2, q->a - 1); 154 } 155 156 for (int i = 1; i <= m; ++i) 157 printf("%d %d ", qry[i].ans1, qry[i].ans2); 158 159 //system("pause"); 160 }
@Author: YouSiki