Tsinsen A1333: 矩阵乘法(整体二分)
Posted Shadowdsp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tsinsen A1333: 矩阵乘法(整体二分)相关的知识,希望对你有一定的参考价值。
题意:……
思路:和之前的第k小几乎一样,只不过把一维BIT换成二维BIT而已。注意二维BIT写法QAQ
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <string> 6 #include <cmath> 7 #include <queue> 8 #include <vector> 9 #include <map> 10 #include <set> 11 #include <stack> 12 using namespace std; 13 #define INF 0x3f3f3f3f 14 #define N 350000 15 typedef long long LL; 16 struct P { 17 int x1, x2, y1, y2, val, id; 18 P () {} 19 P (int x1, int y1, int x2, int y2, int val, int id) : x1(x1), y1(y1), x2(x2), y2(y2), val(val), id(id) {} 20 } q[N], lq[N], rq[N]; 21 int bit[505][505], ans[N], n; 22 23 int lowbit(int x) { return x & (-x); } 24 25 void update(int x, int y, int w) { 26 for(int i = x; i <= n; i += lowbit(i)) 27 for(int j = y; j <= n; j += lowbit(j)) bit[i][j] += w; 28 } 29 30 int query(int x, int y) { 31 int ans = 0; 32 for(int i = x; i; i -= lowbit(i)) 33 for(int j = y; j; j -= lowbit(j)) ans += bit[i][j]; 34 return ans; 35 } 36 37 void Solve(int lask, int rask, int l, int r) { 38 if(lask > rask || l > r) return ; 39 if(l == r) { 40 for(int i = lask; i <= rask; i++) if(q[i].id) ans[q[i].id] = l; 41 return ; 42 } 43 int mid = (l + r) >> 1, lcnt = 0, rcnt = 0; 44 for(int i = lask; i <= rask; i++) { 45 if(!q[i].id) { 46 if(q[i].val <= mid) { 47 update(q[i].x1, q[i].y1, 1); 48 lq[++lcnt] = q[i]; 49 } else rq[++rcnt] = q[i]; 50 } else { 51 int num = query(q[i].x2, q[i].y2) - query(q[i].x1 - 1, q[i].y2) - query(q[i].x2, q[i].y1 - 1) + query(q[i].x1 - 1, q[i].y1 - 1); 52 if(num >= q[i].val) lq[++lcnt] = q[i]; 53 else { 54 q[i].val -= num; 55 rq[++rcnt] = q[i]; 56 } 57 } 58 } 59 for(int i = 1; i <= lcnt; i++) if(!lq[i].id) update(lq[i].x1, lq[i].y1, -1); 60 for(int i = 1; i <= lcnt; i++) q[lask+i-1] = lq[i]; 61 for(int i = 1; i <= rcnt; i++) q[lask+lcnt+i-1] = rq[i]; 62 Solve(lask, lask + lcnt - 1, l, mid); 63 Solve(lask + lcnt, rask, mid + 1, r); 64 } 65 66 int main() { 67 int m, cnt = 0, a; 68 scanf("%d%d", &n, &m); 69 memset(bit, 0, sizeof(bit)); 70 for(int i = 1; i <= n; i++) 71 for(int j = 1; j <= n; j++) { 72 scanf("%d", &a); q[++cnt] = P(i, j, 0, 0, a, 0); 73 } 74 for(int i = 1; i <= m; i++) { 75 ++cnt; q[cnt].id = i; 76 scanf("%d%d%d%d%d", &q[cnt].x1, &q[cnt].y1, &q[cnt].x2, &q[cnt].y2, &q[cnt].val); 77 } 78 Solve(1, cnt, 1, INF); 79 for(int i = 1; i <= m; i++) printf("%d\n", ans[i]); 80 }
以上是关于Tsinsen A1333: 矩阵乘法(整体二分)的主要内容,如果未能解决你的问题,请参考以下文章