zoukankan      html  css  js  c++  java
  • POJ 2155 Matrix (树状数组)

    题意:给定一个0-1矩阵,在线对(x1,y1),(x2,y2)之间的元素置反,在线对特定矩阵求和。

    思路:一道二维树状数组,思路还是挺清晰的,由于是0-1矩阵,只需用tre[][]记录一个元素被置反的次数即可,当对(x1,y1),(x2,y2)区间置反时,需要改动四个地方就是4个角就可以了。为什么呢?如下图,假设A区未需要置反的区域,因为改动A区的左上角时,由树状数组的性质知:A,B,C,D4个区域都是要被置反的,所以在依次置反BD,CD,D,这样,置反的总过程为ABCD,BD,CD,D,这样我们就会发现结果对2取模时,只有A区被置反,B,C,D三个区都没有变化。明白原理之后就好做了。

    A

    B

    C

    D

    #include <iostream>
    #include
    <cstdio>
    #include
    <algorithm>
    #include
    <memory.h>
    #include
    <cmath>
    #include
    <bitset>
    #include
    <queue>
    #include
    <vector>
    using namespace std;

    const int BORDER = (1<<20)-1;
    const int MAXSIZE = 37;
    const int MAXN = 1100;
    const int INF = 1000000000;
    #define CLR(x,y) memset(x,y,sizeof(x))
    #define ADD(x) x=((x+1)&BORDER)
    #define IN(x) scanf("%d",&x)
    #define OUT(x) printf("%d\n",x)
    #define MIN(m,v) (m)<(v)?(m):(v)
    #define MAX(m,v) (m)>(v)?(m):(v)
    #define ABS(x) ((x)>0?(x):-(x))

    int n_tre,n,m;
    int tre[MAXN][MAXN];

    int lowbit(int x)
    {
    return x&(-x);
    }
    void modify(int x,int y,int delta)
    {
    for(int i = x; i <= n_tre; i+= lowbit(i))
    for(int j = y; j <= n_tre; j += lowbit(j))
    {
    tre[i][j]
    += delta;
    }
    }
    int get_sum(const int& x,const int& y)
    {
    int sum = 0;
    for(int i = x; i > 0; i -= lowbit(i))
    for(int j = y; j > 0; j -= lowbit(j))
    {
    sum
    += tre[i][j];
    }
    return sum;
    }
    int init()
    {
    CLR(tre,
    0);
    return 0;
    }
    int input()
    {
    scanf(
    "%d%d",&n,&m);
    return 0;
    }
    int work()
    {
    n_tre
    = n;
    int i,j,tmp,x1,x2,y1,y2;
    char s[10];
    while(m--)
    {
    scanf(
    "%s",s);
    if(s[0] == 'C')
    {
    scanf(
    "%d%d%d%d",&x1,&y1,&x2,&y2);
    modify(x1,y1,
    1);
    modify(x2
    +1,y2+1,1);
    modify(x1,y2
    +1,1);
    modify(x2
    +1,y1,1);
    }
    else
    {
    scanf(
    "%d%d",&x1,&y1);
    printf(
    "%d\n",get_sum(x1,y1)&1);
    }
    }
    printf(
    "\n");
    return 0;
    }
    int main()
    {
    int tt;
    IN(tt);
    while(tt--)
    {
    init();
    input();
    work();
    }
    return 0;
    }

  • 相关阅读:
    CoCreateInstace 返回未知注册类别错误
    WINCE USB驱动组入
    CreateEvent ResetEvent SetEvent
    AppWidget的范例
    ubuntu下解决无声音的方法
    计算几何与图形学有关的几种常用算法
    Android实现GPS的打开与关闭
    深入剖析Android动画(Animation) (闪烁、左右摇摆、上下晃动等效果)
    中兴手机Linux下开发的方法
    移动网络环境下ReadBuffer的使用
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1719133.html
Copyright © 2011-2022 走看看