首页 > 代码库 > HDU 5892 Resident Evil

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,mid16 #define rson rt<<1|1,mid+1,r17 #define fi first18 #define se second19 #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.577215664901532860606512024 #define mod 100000000725 #define inf 0x3f3f3f3f26 #define N 100505027 #define maxn 300128 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("\n");81             }82         }83     }84     return 0;85 }

 

 

 

     

HDU 5892 Resident Evil