• HDU 5892 Resident Evil


    题目链接:传送门

    题目大意:有50种动物,给你n*n的矩阵,m次操作,P代表加入操作,在左上角 x1,y1 到右下角 x2,y2,的矩形范围内加入

         种类为x,数量为y的动物。

         Q代表询问操作,在左上角 x1,y1 到右下角 x2,y2,对于1~50种动物,如果数量之和为偶数,输出1,否则输出2。

    题目思路:树状数组 区间异或,区间查询。

    /*--------------------------------------------------分割线-------------------------------------------------------------*/

    以下均考虑树状数组维护异或值

    我们首先要知道树状数组都是向后更新,向前查询的。

    首先考虑简单的问题

    如果要求一维空间,单点修改,区间查询,那这个就直接像普通树状数组那样,修改和查询时把+改成^就行了。

    如果要求一维空间,区间修改,区间查询,这时候就不能像普通树状数组那么改了。不信可以试试。:)

      如果异或更新 [x,y] ^v

      我们知道这样一个性质,假如对于位置 x,那么x+1,x+3,x+7...这些位置上的值是不会被V影响的。

      因为更新时这些位置上的数异或V偶数次,值不会受影响。只有与 x 奇偶性相同的位置 x+2,x+4...才会被更新。

      因此,我们可以开个二维数组tree[2][maxn],只修改 x奇偶性对应的那一维,比如可以写成 x&1,偶数修改0,奇数修改1

      查询时对应奇偶性查询。

    本题要求二维空间,区间修改,区间查询,那么扩展一下,开4个数组即可。

    然后我们把对应的50种动物状态压缩 1<<50,开LL tree[4][3001][3001],这样不会爆空间。

    然后对于加入的动物数量,首先不用去管面积,直接用给的数量值(因为 偶*奇==偶,偶*偶==偶)

    所以只要加入偶数数量就不用管,因为数量永远是偶数,而初始值0也是偶数,也就是对答案没影响。

    对于加入奇数的情况,就必须老老实实加入(奇*奇==奇,奇*偶==偶),面积会对奇数情况有影响。

    之后只需按上诉方法异或即可。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <cstring>
     7 #include <stack>
     8 #include <cctype>
     9 #include <queue>
    10 #include <string>
    11 #include <vector>
    12 #include <set>
    13 #include <map>
    14 #include <climits>
    15 #define lson rt<<1,l,mid
    16 #define rson rt<<1|1,mid+1,r
    17 #define fi first
    18 #define se second
    19 #define ping(x,y) ((x-y)*(x-y))
    20 #define mst(x,y) memset(x,y,sizeof(x))
    21 #define mcp(x,y) memcpy(x,y,sizeof(y))
    22 using namespace std;
    23 #define gamma 0.5772156649015328606065120
    24 #define mod 1000000007
    25 #define inf 0x3f3f3f3f
    26 #define N 1005050
    27 #define maxn 3001
    28 typedef pair<int,int> PII;
    29 typedef long long LL;
    30 
    31 int n,m,k,x,y,v;
    32 LL tree[2][2][3001][3001];
    33 int x1,y1,x2,y2;
    34 LL mon[50];
    35 void add(int x,int y,LL v){
    36     for(int i=x;i<=n;i+=(i&-i))
    37     for(int j=y;j<=n;j+=(j&-j))
    38         tree[x&1][y&1][i][j]^=v;
    39 }
    40 LL query(int x,int y){
    41     LL res=0;
    42     for(int i=x;i;i-=(i&-i))
    43     for(int j=y;j;j-=(j&-j))
    44         res^=tree[x&1][y&1][i][j];
    45     return res;
    46 }
    47 int main(){
    48     //freopen("in.txt","r",stdin);
    49     int i,j,group;
    50     char ch;
    51     while(scanf("%d%d",&n,&m)!=EOF){
    52         mst(tree,0);
    53         while(m--){
    54             scanf(" %c%d%d%d%d",&ch,&x1,&y1,&x2,&y2);
    55             if(ch=='P'){
    56                 mst(mon,0);
    57                 scanf("%d",&k);
    58                 while(k--){
    59                     scanf("%d%d",&x,&y);
    60                     --x;
    61                     mon[x]+=y;
    62                 }
    63                 LL temp=0;
    64                 for(i=0; i<50; ++i){
    65                     if(mon[i]&1)
    66                     temp|=(1ll<<i);
    67                 }
    68                 ++x2;++y2;
    69                 add(x1,y1,temp);
    70                 add(x2,y2,temp);
    71                 add(x1,y2,temp);
    72                 add(x2,y1,temp);
    73             }
    74             else{
    75                 --x1,--y1;
    76                 LL temp=query(x1,y1)^query(x2,y2)^query(x1,y2)^query(x2,y1);
    77                 for(i=0;i<50;++i)
    78                     if(temp&(1ll<<i))printf("2 ");
    79                     else printf("1 ");
    80                 printf("
    ");
    81             }
    82         }
    83     }
    84     return 0;
    85 }

         

  • 相关阅读:
    ZK简单操作
    Java 混沌实验执行器 chaosblade-exec-jvm
    数仓分层
    维护大数据系统时遇到的几个问题及解决方案
    hotkey
    C# 构建一个TCP和SerialPort通信的通用类(下)
    C# 构建一个TCP和SerialPort通信的通用类(上)
    Prism框架中的DelagateCommand(下)
    Prism框架中的DelagateCommand(上)
    如何搭建自己的Nuget服务器(上)
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5887157.html
Copyright © 2020-2023  润新知