zoukankan      html  css  js  c++  java
  • poj 2155:Matrix(二维线段树,矩阵取反,好题)

    Matrix
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 17880   Accepted: 6709

    Description

    Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1 <= i, j <= N). 

    We can change the matrix in the following way. Given a rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2), we change all the elements in the rectangle by using "not" operation (if it is a '0' then change it into '1' otherwise change it into '0'). To maintain the information of the matrix, you are asked to write a program to receive and execute two kinds of instructions. 

    1. C x1 y1 x2 y2 (1 <= x1 <= x2 <= n, 1 <= y1 <= y2 <= n) changes the matrix by using the rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2). 
    2. Q x y (1 <= x, y <= n) querys A[x, y]. 

    Input

    The first line of the input is an integer X (X <= 10) representing the number of test cases. The following X blocks each represents a test case. 

    The first line of each block contains two numbers N and T (2 <= N <= 1000, 1 <= T <= 50000) representing the size of the matrix and the number of the instructions. The following T lines each represents an instruction having the format "Q x y" or "C x1 y1 x2 y2", which has been described above. 

    Output

    For each querying output one line, which has an integer representing A[x, y]. 

    There is a blank line between every two continuous test cases. 

    Sample Input

    1
    2 10
    C 2 1 2 2
    Q 2 2
    C 2 1 2 1
    Q 1 1
    C 1 1 2 1
    C 1 2 1 2
    C 1 1 2 2
    Q 1 1
    C 1 1 2 1
    Q 2 1
    

    Sample Output

    1
    0
    0
    1
    

    Source

    POJ Monthly,Lou Tiancheng
     
      二维线段树,矩阵取反,好题
     
      题意
      
      思路
      矩阵节点的值为是否取反,0为不取反,1为取反,暂称为取反值。
      取反操作的时候先找到这个矩阵代表的节点,然后将这个节点的值+1再模2,即取反。
      查询的时候,将(x,y)这个坐标经过的所有矩阵的取反值加起来,每次%2,最后那个值就为这个坐标最后的值。
      为什么%2,因为不是1就是0,矩阵记录了取反值,找这个坐标的过程中,经过的矩阵如果取反值为1,则结果变为0,在经过一个取反值为1的矩阵,结果又变为1…… 直到加到要找的坐标的取反值,这个结果记录的值就是这个坐标的取反值。这个时候输出结果。
     
      代码
     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 using namespace std;
     5 
     6 #define MAXN 1100
     7 
     8 int tree[MAXN*3][MAXN*3],s;
     9 
    10 void Negate_y(int d,int dy,int L,int R,int y1,int y2)    //取反操作
    11 {    
    12     if(L==y1 && R==y2){    //将这个矩阵的所有元素记录为取反
    13         tree[d][dy] = (tree[d][dy]+1) % 2;
    14         return ;
    15     }
    16 
    17     int mid = (L+R)>>1;
    18     if(mid>=y2)
    19         Negate_y(d,dy<<1,L,mid,y1,y2);
    20     else if(mid<y1)
    21         Negate_y(d,dy<<1|1,mid+1,R,y1,y2);
    22     else{
    23         Negate_y(d,dy<<1,L,mid,y1,mid);
    24         Negate_y(d,dy<<1|1,mid+1,R,mid+1,y2);
    25     }
    26 }
    27 
    28 void Negate_x(int d,int L,int R,int x1,int y1,int x2,int y2)        //取反操作
    29 {
    30     if(L==x1 && R==x2){    //找到行块
    31         Negate_y(d,1,1,s,y1,y2);    
    32         return ;
    33     }
    34 
    35     int mid = (L+R)>>1;
    36     if(mid>=x2)
    37         Negate_x(d<<1,L,mid,x1,y1,x2,y2);
    38     else if(mid<x1)
    39         Negate_x(d<<1|1,mid+1,R,x1,y1,x2,y2);
    40     else{
    41         Negate_x(d<<1,L,mid,x1,y1,mid,y2);
    42         Negate_x(d<<1|1,mid+1,R,mid+1,y1,x2,y2);
    43     }
    44 }
    45 
    46 
    47 int Query_y(int d,int dy,int L,int R,int r)    //查询
    48 {
    49     if(L==R)    //找到要找的坐标,输出这个坐标对应的值
    50         return tree[d][dy];
    51 
    52     //没找到
    53     int mid = (L+R)>>1;
    54     if(mid >= r)
    55         return (Query_y(d,dy<<1,L,mid,r)+tree[d][dy]) % 2;
    56     else
    57         return (Query_y(d,dy<<1|1,mid+1,R,r)+tree[d][dy]) % 2;
    58 }
    59 
    60 int Query_x(int d,int L,int R,int l,int r)    //查询
    61 {
    62     if(L==R){    //找到要找的行块,继续查找列块
    63         return Query_y(d,1,1,s,r);
    64     }
    65 
    66     //没找到
    67     int mid = (L+R)>>1;
    68     if(mid >= l)
    69         return (Query_x(d<<1,L,mid,l,r) + Query_y(d,1,1,s,r)) % 2;
    70     else
    71         return (Query_x(d<<1|1,mid+1,R,l,r) + Query_y(d,1,1,s,r)) % 2;
    72 }
    73 
    74 int main()
    75 {
    76     int X,T,x,y,x1,y1,x2,y2;
    77     scanf("%d",&X);
    78     while(X--){
    79         memset(tree,0,sizeof(tree));
    80         scanf("%d%d",&s,&T);
    81         while(T--){
    82             char c[5];
    83             scanf("%s",c);
    84             if(c[0]=='C'){
    85                 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    86                 Negate_x(1,1,s,x1,y1,x2,y2);
    87             }
    88             else if(c[0]=='Q'){
    89                 scanf("%d%d",&x,&y);
    90                 printf("%d
    ",Query_x(1,1,s,x,y));
    91             }
    92         }
    93         if(X!=0)
    94             printf("
    ");
    95     }
    96 
    97     return 0;
    98 }

    Freecode : www.cnblogs.com/yym2013

  • 相关阅读:
    leetcode 576. Out of Boundary Paths 、688. Knight Probability in Chessboard
    leetcode 129. Sum Root to Leaf Numbers
    leetcode 542. 01 Matrix 、663. Walls and Gates(lintcode) 、773. Sliding Puzzle 、803. Shortest Distance from All Buildings
    leetcode 402. Remove K Digits 、321. Create Maximum Number
    leetcode 139. Word Break 、140. Word Break II
    leetcode 329. Longest Increasing Path in a Matrix
    leetcode 334. Increasing Triplet Subsequence
    leetcode 403. Frog Jump
    android中webView加载H5,JS不能调用问题的解决
    通过nginx中转获取不到IP的问题解决
  • 原文地址:https://www.cnblogs.com/yym2013/p/3854331.html
Copyright © 2011-2022 走看看