zoukankan      html  css  js  c++  java
  • POJ_2155 Matrix 【二维树状数组】

    一、题面

    POJ2155

    二、分析

      楼教主出的题,是二维树状数组非常好的题,还结合了开关问题(开关变化的次数如果为偶数,状态不变,奇数状态相反)。

      题意就是给了一个二维的坐标平面,每个点初始值都是0,然后给一个矩形的区域,对该区域的点的状态进行反转。然后在中间插有查询,查该点的状态。

      其实,还是对反转次数的一个研究,这里为了能快速的查找一个点的反转次数,加上又是二维,且有区间修改,所以选择二维树状数组进行处理,整个二维数组记录的就是反转的次数。

      每反转一次,就对整个矩形区间进行修改,反转次数加1,最终查询的时候就是查一共反转了多少次,记得取余2,如果是偶数,就不变,是奇数,就变1。

      注意处理二维树状数组区间更新的时候,假设给的矩形对角线的点为(x1,y1),(x2,y2)。那么更新的时候是

    $add(x1,y1,v) + add(x1,y2+1, -v) + add(x2+1, y1, -v)  + add(x2+1,y2+1,v)$

    为什么这样,看下图,因为你如果只更新(x1,y1),那么就会更新多的区域,就要想办法减去,但是减了之后,发现又减重了一部分,所以需要又加回来。

    三、AC代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 
     5 using namespace std;
     6 
     7 const int MAXN = 1e3 + 15;
     8 
     9 int BIT[MAXN][MAXN];
    10 
    11 void add(int x, int y, int v)
    12 {
    13     for(; x < MAXN; x += x & -x)
    14     {
    15         for(int j = y; j < MAXN; j += j & -j)
    16         {
    17             BIT[x][j] += v;
    18         }
    19     }
    20 }
    21 
    22 int sum(int x, int y)
    23 {
    24     int ans = 0;
    25     for(; x; x -= x & -x)
    26     {
    27         for(int j = y; j; j -= j & -j)
    28         {
    29             ans += BIT[x][j];
    30         }
    31     }
    32     return ans%2;
    33 }
    34 
    35 void update(int x1, int y1, int x2, int y2, int v)
    36 {
    37     add(x1, y1, v);
    38     add(x2 + 1, y2 + 1, v);
    39     add(x1, y2 + 1, -v);
    40     add(x2 + 1, y1, -v);
    41 }
    42 
    43 int main()
    44 {
    45     //freopen("input.txt", "r", stdin);
    46     int T;
    47     scanf("%d", &T);
    48     while(T)
    49     {
    50         int N, Q, x1, y1, x2, y2;
    51         char c;
    52         memset(BIT, 0, sizeof(BIT));
    53         scanf("%d %d", &N, &Q);
    54         for(int i = 0; i < Q; i++)
    55         {
    56             getchar();
    57             scanf("%c %d %d", &c, &x1, &y1);
    58 
    59             if(c == 'C')
    60             {
    61                 scanf("%d %d", &x2, &y2);
    62                 update(x1, y1, x2, y2, 1);
    63             }
    64             else
    65             {
    66                 printf("%d
    ", sum(x1, y1));
    67             }
    68         }
    69         if(--T)
    70             printf("
    ");
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    静态初始化块的执行顺序
    Integer练习
    关于厦门电信访问不了中文域名的原因
    获得库每个表的记录数和容量,sp_msforeachtable是MS未公开的存储过程
    ASP.NET State Service服务的作用
    强烈后悔用VS2008
    sp_addextendedproc
    DataSet SELECT DISTINCT Helper Class in Visual C# .NET
    今天买了5个冰淇淋
    TSQL常用字符串函数
  • 原文地址:https://www.cnblogs.com/dybala21/p/10537114.html
Copyright © 2011-2022 走看看