zoukankan      html  css  js  c++  java
  • 【BZOJ 1176 2683】Mokia

    Description

    维护一个W*W的矩阵,初始值均为S.每次操作可以增加某格子的权值,或询问某子矩阵的总权值.修改操作数M<=160000,询问数Q<=10000,W<=2000000.(在2683中,没有S,初始值为0)。

    Input

    第一行两个整数,S,W;其中S为矩阵初始值;W为矩阵大小

    接下来每行为一下三种输入之一(不包含引号):

    "1 x y a"

    "2 x1 y1 x2 y2"

    "3"

    输入1:你需要把(x,y)(第x行第y列)的格子权值增加a

    输入2:你需要求出以左上角为(x1,y1),右下角为(x2,y2)的矩阵内所有格子的权值和,并输出

    输入3:表示输入结束

    Output

    对于每个输入2,输出一行,即输入2的答案

    Sample Input

    0 4
    1 2 3 3
    2 1 1 3 3
    1 2 2 2
    2 2 2 3 4
    3

    Sample Output

    3
    5

    HINT 

    保证答案不会超过int范围

    分析:

      对操作进行分治,左边的修改必定会影响右边的查询,这一部分只要对x排序,做树状数组就好了。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 struct A
     6 {
     7     int x, y, pos, ctrl, ans;
     8 } t[200010], q[200010];
     9 
    10 inline bool cmp(const A &a, const A &b)
    11 {
    12     return a.pos < b.pos;
    13 }
    14 
    15 int s, w, k, x, y, a, b, cnt;
    16 int key[2000010], late[2000010], now;
    17 
    18 void modify(int pos, int data)
    19 {
    20     for ( ; pos <= w + 1; pos += pos & -pos)
    21     {
    22         if (late[pos] != now) key[pos] = 0;
    23         late[pos] = now, key[pos] += data;
    24     }
    25 }
    26 
    27 int query(int pos)
    28 {
    29     int ret = 0;
    30     for ( ; pos; pos -= pos & -pos)
    31         if (late[pos] == now) ret += key[pos];
    32     return ret;
    33 }
    34 
    35 void cdq(int left, int right)
    36 {
    37     if (left == right) return;
    38     int mid = left + right >> 1;
    39     cdq(left, mid); cdq(mid + 1, right);
    40     now++;
    41     for (int i = mid + 1, j = left; i <= right; i++)
    42     {
    43         for ( ; j <= mid && q[j].x <= q[i].x; j++)
    44             if (q[j].ctrl == 0) modify(q[j].y, q[j].ans);
    45         if (q[i].ctrl > 0) q[i].ans += query(q[i].y);
    46     }
    47     for (int i = left, j = left, k = mid + 1; i <= right; i++)
    48     {
    49         if ((q[j].x <= q[k].x && j <= mid) || k > right)
    50             t[i] = q[j++];
    51         else t[i] = q[k++];
    52     }
    53     memcpy(q + left, t + left, sizeof(q[0]) * (right - left + 1));
    54 }
    55 
    56 int main()
    57 {
    58     scanf("%d%d", &s, &w);
    59     while (k != 3)
    60     {
    61         scanf("%d", &k);
    62         if (k == 1)
    63         {
    64             scanf("%d%d%d", &x, &y, &a);
    65             cnt++, q[cnt] = (A) {x + 1, y + 1, cnt, 0, a};
    66         }
    67         if (k == 2)
    68         {
    69             scanf("%d%d%d%d", &x, &y, &a, &b);
    70             a++, b++;
    71             cnt++, q[cnt] = (A) {x, y, cnt, 1, x * y * s};
    72             cnt++, q[cnt] = (A) {a, b, cnt, 2, a * b * s};
    73             cnt++, q[cnt] = (A) {a, y, cnt, 2, a * y * s};
    74             cnt++, q[cnt] = (A) {x, b, cnt, 2, x * b * s};
    75         }
    76     }
    77     cdq(1, cnt);
    78     std::sort(q + 1, q + cnt + 1, cmp);
    79     for (int i = 1; i <= cnt; i++)
    80     {
    81         if (q[i].ctrl == 1)
    82         {
    83             printf("%d
    ", q[i].ans + q[i + 1].ans - q[i + 2].ans - q[i + 3].ans);
    84         }
    85     }
    86 }
  • 相关阅读:
    指针数组和数组指针表示二维数组
    scanf与getchar()区别
    选择循环
    朴素的思想
    asp.net中word转html碰到的权限异常问题(转)
    MAC下安装Fiddler抓包工具
    抓包工具charles的使用
    mysql 命令大全
    利用反射拼接SQL查询条件字符串
    赚自己的淘宝佣金,让返利网无路可走
  • 原文地址:https://www.cnblogs.com/lightning34/p/4641286.html
Copyright © 2011-2022 走看看