码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ2738 矩阵乘法

时间:2015-02-23 18:59:16      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:

神题。。。

首先我们要想到。。。从小到大一个个加入矩阵里的数,然后看每个数对每个询问的贡献,但复杂度不对

其次,我们可以二分啊!先加前一半小的数,再加后一半大的数,看每个询问在前一半是否已经得到答案了(貌似叫整体二分?)

然后,为了不加一倍空间,我写的类似快排一样的东西。。。简直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 }
View Code

 (p.s. 跪求大神讲解整体二分和cdq分治区别,虽然我都不会= =b)

BZOJ2738 矩阵乘法

标签:

原文地址:http://www.cnblogs.com/rausen/p/4298183.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!