神题。。。
首先我们要想到。。。从小到大一个个加入矩阵里的数,然后看每个数对每个询问的贡献,但复杂度不对
其次,我们可以二分啊!先加前一半小的数,再加后一半大的数,看每个询问在前一半是否已经得到答案了(貌似叫整体二分?)
然后,为了不加一倍空间,我写的类似快排一样的东西。。。简直sxbk边界怎么都搞不定。。。
最后,bz的评测姬傲娇T^T,一样的程序前天交WA,今天交AC。。。
1 /************************************************************** 2 Problem: 2738 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:10192 ms 7 Memory:6436 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <algorithm> 12 13 using namespace std; 14 const int N = 505; 15 const int Cnt_q = 6e4 + 5; 16 17 inline int read() { 18 int x = 0; 19 char ch = getchar(); 20 while (ch < '0' || '9' < ch) 21 ch = getchar(); 22 while ('0' <= ch && ch <= '9') { 23 x = x * 10 + ch - '0'; 24 ch = getchar(); 25 } 26 return x; 27 } 28 29 struct data { 30 int x, y, v; 31 data() {} 32 data(int _x, int _y, int _v) : x(_x), y(_y), v(_v) {} 33 34 inline bool operator < (const data &a) const { 35 return v < a.v; 36 } 37 } a[N * N + 5]; 38 39 struct query { 40 int x1, x2, y1, y2, k, id; 41 42 inline void read_in(int i) { 43 x1 = read(), y1 = read(), x2 = read(), y2 = read(); 44 k = read(), id = i; 45 } 46 } q[Cnt_q]; 47 48 int n, bit[N][N], ans[Cnt_q], now; 49 50 #define lowbit(x) (x & -x) 51 inline void bit_modify(int x, int y, int d) { 52 int i, j; 53 for (i = x; i <= n; i += lowbit(i)) 54 for (j = y; j <= n; j += lowbit(j)) 55 bit[i][j] += d; 56 } 57 58 inline int bit_query(int x, int y) { 59 int i, j, res = 0; 60 for (i = x; i; i -= lowbit(i)) 61 for (j = y; j; j -= lowbit(j)) 62 res += bit[i][j]; 63 return res; 64 } 65 #undef lowbit 66 67 inline bool check(int i) { 68 int tmp = bit_query(q[i].x2, q[i].y2) + bit_query(q[i].x1 - 1, q[i].y1 - 1) 69 - bit_query(q[i].x2, q[i].y1 - 1) - bit_query(q[i].x1 - 1, q[i].y2); 70 return q[i].k <= tmp; 71 } 72 73 void work(int l, int r, int L, int R) { 74 if (L > R) return; 75 if (l == r) { 76 int i; 77 for (i = L; i <= R; ++i) 78 ans[q[i].id] = l; 79 return; 80 } 81 int mid = l + r >> 1, i = L, j = R; 82 while (now != n * n && a[now + 1].v <= mid) 83 ++now, bit_modify(a[now].x, a[now].y, 1); 84 while (now && a[now].v > mid) 85 bit_modify(a[now].x, a[now].y, -1), --now; 86 87 while (i <= j) { 88 while (i <= j && check(i)) ++i; 89 while (i <= j && !check(j)) --j; 90 if (i < j) { 91 swap(q[i], q[j]); 92 ++i, --j; 93 } 94 } 95 work(l, mid, L, j); 96 work(mid + 1, r, i, R); 97 } 98 99 #define w(x, y) (x - 1) * n + y 100 int main() { 101 int Q, i, j, mx = 0; 102 n = read(), Q = read(); 103 for (i = 1; i <= n; ++i) 104 for (j = 1; j <= n; ++j) { 105 a[w(i, j)] = data(i, j, read()); 106 mx = max(mx, a[w(i, j)].v); 107 } 108 sort(a + 1, a + n * n + 1); 109 for (i = 1; i <= Q; ++i) 110 q[i].read_in(i); 111 work(0, mx, 1, Q); 112 for (i = 1; i <= Q; ++i) 113 printf("%d\n", ans[i]); 114 return 0; 115 }
(p.s. 跪求大神讲解整体二分和cdq分治区别,虽然我都不会= =b)
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen