hdu5892Resident Evil(2016沈阳网络赛A)

11 篇文章 0 订阅
10 篇文章 0 订阅

hdu5892ResidentEvil(2016沈阳网络赛A)

        裸的二维树状数组求和,比赛的时候竟然没发现。实际上XOR运算等效于模2意义下的加减运算。这题唯一用到的技巧是将50个怪兽的状态压缩成250 统一处理以节省时间空间。至于二维树状数组区间求和和查询,可以通过推公式的方法先将问题转化成单点修改,区间查询,再用矩形加减即可。

         最后注意一次修改同一只怪兽可能出现多次,还有PE问题,行末没空格算PE ⊙﹏⊙。

 

//#include <bits\stdc++.h>
//#pragma comment(linker,"/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <algorithm>
#include <bitset>
 
#define sqr(x) ((x)*(x))           
#define lson (p<<1)
#define rson (lson | 1)
#define EPS 1e-10
#define PII pair<int,int>
#define PLI pair<LL,int>
#define PLL pair<LL,LL>
#define PIL pair<int,LL>
#define mk(x,y) make_pair(x,y)
#define lowbit(x) (x&(-x))
using namespace std;
template <class T>
inline void read(T &x){char c = getchar();x = 0;while(!isdigit(c))c = getchar();while(isdigit(c)){ x = x * 10 + c-'0';c = getchar();}}
template <class T>
inline void rd(T &res) {static char ch; boolsgn = false;while (ch = getchar(), ch <'0' || ch > '9') if (ch == '-') sgn =true;
          res = ch - 48;while(ch = getchar(), ch >= '0' && ch<= '9') res = res * 10 + ch - 48;res = sgn ? -res : res;}
template <class T> void Out(T a) { if(a < 0){putchar('-');a= -a;}if(a >= 10)Out(a / 10);putchar(a% 10 + '0');  } 
typedef unsigned long long LL;
const int N = 3010;
LL c[4][N][N];
int n;
void add(int id,int x,int y,LL val)
{
   for(;x<=n;x+=lowbit(x))
        for(int j=y;j<=n;j+=lowbit(j))
            c[id][x][j]^= val;
}
void add(int x,int y,LL val)
{
   add(0,x,y,val);
   if(y&1) add(1,x,y,val);
   if(x&1) add(2,x,y,val);
   if((x*y)&1)add(3,x,y,val);
}
void update(int x1,int y1,int x2,int y2,LLx)
{
   add(x1,y1,x),add(x1,y2,x),add(x2,y1,x),add(x2,y2,x);
}
LL get(int id,int x,inty)
{
   LL ans = 0;
   for(;x;x-=lowbit(x))
        for(int j=y;j;j-=lowbit(j))
            ans ^= c[id][x][j];
   return ans;
}
LL get(int x,int y)
{
   LL ans = get(3,x,y);
   int xx = x + 1,yy = y + 1;
   if( (xx*yy) & 1)ans ^= get(0,x,y);
   if( (xx) & 1)ans ^= get(1,x,y);
   if( (yy) & 1)ans ^= get(2,x,y);
   return ans;
}
LL query(int x1,int y1,intx2,int y2)
{
   return get(x2,y2)^ get(x1,y2) ^ get(x2,y1) ^ get(x1,y1);
}
char s[10];
LL Pow[55];
int main()
{
   int m;
   Pow[0] = 1;
   for(int i=1;i<55;i++)
       Pow[i] = Pow[i-1] << 1LL;
   while(~scanf("%d%d",&n,&m))
   {
       memset(c,0,sizeof(c));
        while(m--)
        {
            int x1,y1,x2,y2,k,l,r;
            scanf(" %s",s);
            rd(y1),rd(x1),rd(y2),rd(x2);
            if(s[0] == 'P')
            {
                rd(k);
                LL x = 0;
                while(k--)
               {
                    rd(l),rd(r);
                    if(r&1) x^=Pow[l];
                }
                update(x1,y1,x2+1,y2+1,x);
            }else
            {
                LL ans = query(x1-1,y1-1,x2,y2);
                for(int i=1;i<=50;i++)
                {
                    if(ans&Pow[i]) putchar('2'); elseputchar('1');
                    putchar(' ');
                }
                puts("");
            }
        }
   }
   return 0;
}
 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值