Tsinsen A1333: 矩阵乘法(整体二分)

Posted Shadowdsp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tsinsen A1333: 矩阵乘法(整体二分)相关的知识,希望对你有一定的参考价值。

http://www.tsinsen.com/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: 矩阵乘法(整体二分)的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ_2738_矩阵乘法_整体二分

[BZOJ2738]矩阵乘法 整体二分+二维树状数组

bzoj2738矩阵乘法 整体二分 二维树状数组

BZOJ 2738 矩阵乘法(整体二分+二维树状数组)

bzoj2738 矩阵乘法 整体二分

P1527 [国家集训队]矩阵乘法