problem Iahub and Xors

题目大意

  一个n*n的矩阵,要求支持两种操作。

  操作1:将一个子矩阵的所有值异或某个数。

  操作2:询问某个子矩阵的所以值的异或和。

解题分析

  由于异或的特殊性,可以用二维树状数组来维护。

  因为同一个值只有异或奇数次才有效,因此若单点修改某个点,那么其影响的点为与其行和列奇偶性相同的点,故可以开4个二维树状数组来维护。

  如果是区间修改x1,y1,x2,y2,则只需单点修改(x1,y1)、(x1,y2+1)、(x2+1,y2)、(x2+1,y2+1)

  如果是区间询问x1,y1,x2,y2,则答案为(x2,y2)^(x1-1,y1-1)^(x1-1,y2)^(x2,y1-1)

参考程序

二维树状数组

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std; #define N 1008
#define M 50008
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define clr(x,v) memset(x,v,sizeof(x));
#define bitcnt(x) __builtin_popcount(x)
#define rep(x,y,z) for (int x=y;x<=z;x++)
#define repd(x,y,z) for (int x=y;x>=z;x--)
const int mo = ;
const int inf = 0x3f3f3f3f;
const int INF = ;
/**************************************************************************/ struct Binary_Indexd_Tree{
LL a[][][N][N];
int n;
void init(int x)
{
n=x;
clr(a,);
}
void update(int x,int y,LL val)
{
for (int i=x;i<=n+;i+=i & (-i))
for (int j=y;j<=n+;j+=j & (-j))
a[x & ][y & ][i][j]^=val;
}
LL query(int x,int y)
{
LL res=;
for (int i=x;i;i-=i & (-i))
for (int j=y;j;j-=j & (-j))
res^=a[x & ][y & ][i][j];
return res;
}
}T; int main()
{
int n,q;
scanf("%d",&n);
T.init(n);
scanf("%d",&q);
rep(i,,q)
{
int op,x1,y1,x2,y2;
LL val;
scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2);
if (op==)
{
scanf("%I64d",&val);
T.update(x1,y1,val);
T.update(x1,y2+,val);
T.update(x2+,y1,val);
T.update(x2+,y2+,val);
}
else
{
LL res=T.query(x2,y2);
res^=T.query(x1-,y1-);
res^=T.query(x1-,y2);
res^=T.query(x2,y1-);
printf("%I64d\n",res);
}
}
}

四分树 T了= =

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std; #define N 3008
#define M 50008
#define LL long long
#define son(x) rt*4+x-3
#define clr(x,v) memset(x,v,sizeof(x));
#define bitcnt(x) __builtin_popcount(x)
#define rep(x,y,z) for (int x=y;x<=z;x++)
#define repd(x,y,z) for (int x=y;x>=z;x--)
const int mo = ;
const int inf = 0x3f3f3f3f;
const int INF = ;
/**************************************************************************/ LL tag[N*N],lazy[N*N];
struct interval{
int l,r;
interval(int l=,int r=):l(l),r(r){}
int mid(){
return l+r>>;
}
int len(){
return r-l+;
}
interval left(){
return interval(l,mid());
}
interval right(){
return interval(mid()+,r);
}
bool intersect(interval x)
{
return !(x.r<l || x.l>r);
}
bool contain(interval x)
{
return l<=x.l && x.r<=r;
}
bool pt()
{
printf("%d %d ",l,r);
}
};
void pushup(int rt)
{
tag[rt]=tag[son()]^tag[son()]^tag[son()]^tag[son()];
}
void pushdown(int rt,interval x,interval y)
{
if (lazy[rt])
{
lazy[son()]^=lazy[rt];
lazy[son()]^=lazy[rt];
lazy[son()]^=lazy[rt];
lazy[son()]^=lazy[rt];
if (x.left().len() * y.left().len() & ) tag[son()]^=lazy[rt];
if (x.left().len() * y.right().len() & ) tag[son()]^=lazy[rt];
if (x.right().len() * y.left().len() & ) tag[son()]^=lazy[rt];
if (x.right().len() * y.right().len() & ) tag[son()]^=lazy[rt];
lazy[rt]=;
}
}
void build(interval x,interval y,int rt)
{
tag[rt]=; lazy[rt]=;
if (x.len()<= || y.len()<=) return;
if (x.len()== && y.len()==)
{
return;
}
build(x.left(),y.left(),son());
build(x.left(),y.right(),son());
build(x.right(),y.left(),son());
build(x.right(),y.right(),son());
pushup(rt);
}
LL query(interval X,interval Y,interval x,interval y,int rt)
{
if (x.len()<= || y.len()<=) return ;
if (!x.intersect(X) || !y.intersect(Y)) return ;
if (X.contain(x) && Y.contain(y))
{
return tag[rt];
}
pushdown(rt,x,y);
LL res=;
res^=query(X,Y,x.left(),y.left(),son());
res^=query(X,Y,x.left(),y.right(),son());
res^=query(X,Y,x.right(),y.left(),son());
res^=query(X,Y,x.right(),y.right(),son());
//x.pt(); y.pt(); printf("%lld\n",res);
return res;
}
void update(interval X,interval Y,LL val,interval x,interval y,int rt)
{
if (x.len()<= || y.len()<=) return;
if (!X.intersect(x) || !Y.intersect(y)) return;
if (X.contain(x) && Y.contain(y))
{
if (x.len()*y.len() & ) tag[rt]^=val;
lazy[rt]^=val;
return;
}
pushdown(rt,x,y);
update(X,Y,val,x.left(),y.left(),son());
update(X,Y,val,x.left(),y.right(),son());
update(X,Y,val,x.right(),y.left(),son());
update(X,Y,val,x.right(),y.right(),son());
pushup(rt);
}
int main()
{
int n,q;
scanf("%d%d",&n,&q);
build(interval(,n),interval(,n),);
while (q--)
{
int x1,y1,x2,y2,op,val;
scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2);
if (op==)
{
scanf("%d",&val);
update(interval(x1,x2),interval(y1,y2),val,interval(,n),interval(,n),);
}
else
{
cout << query(interval(x1,x2),interval(y1,y2),interval(,n),interval(,n),)<< endl;
}
}
}

codeforces 341d (树状数组)的更多相关文章

  1. HDU 3333 | Codeforces 703D 树状数组、离散化

    HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333 这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序.这里我们需要离散化 ...

  2. CodeForces 396C 树状数组 + DFS

    本主题开始看到以为段树或树状数组,但是,对于一个节点的有疑问的所有子节点的加权,这一条件被视为树的根,像 然后1号是肯定在第一层中,然后建立一个单向侧倒查,然后记录下来 其中每个节点 层,终于 两个节 ...

  3. Codeforces 276E(树状数组)

    题意:一棵树有n个节点,1是根节点,根节点的子节点是单链,然后如今有两种操作0 v x d表示距离节点v为d的节点权值都加x,操作1 v问v节点的权值,初始节点权值都是0. 题解:看了别人的题解才会的 ...

  4. Tokitsukaze and Strange Rectangle CodeForces - 1191F (树状数组,计数)

    大意: 给定$n$个平面点, 定义集合$S(l,r,a)$表示横坐标$[l,r]$纵坐标$[a,\infty]$内的所有点. 求可以得到多少种不同的集合. 从上往下枚举底层最右侧点, 树状数组统计贡献 ...

  5. codeforces 629D 树状数组+LIS

    题意:n个圆柱形蛋糕,给你半径 r 和高度 h,一个蛋糕只能放在一个体积比它小而且序号小于它的蛋糕上面,问你这样形成的上升序列中,体积和最大是多少 分析:根据他们的体积进行离散化,然后建树状数组,按照 ...

  6. Encryption (hard) CodeForces - 958C3 (树状数组)

    大意: 给定序列$a$, 要求将$a$分成$k$个非空区间, 使得区间和模$p$的和最小, 要求输出最小值. $k$和$p$比较小, 直接暴力$dp$, 时间复杂度是$O(nklogp)$, 空间是$ ...

  7. codeforces 597C (树状数组+DP)

    题目链接:http://codeforces.com/contest/597/problem/C 思路:dp[i][j]表示长度为i,以j结尾的上升子序列,则有dp[i][j]= ∑dp[i-1][k ...

  8. Codeforces 597C. Subsequences (树状数组+dp)

    题目链接:http://codeforces.com/contest/597/problem/C 给你n和数(1~n各不同),问你长为k+1的上升自序列有多少. dp[i][j] 表示末尾数字为i 长 ...

  9. Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum (离线树状数组+前缀xor)

    题目链接:http://codeforces.com/contest/703/problem/D 给你n个数,m次查询,每次查询问你l到r之间出现偶数次的数字xor和是多少. 我们可以先预处理前缀和X ...

随机推荐

  1. 模板列onclick事件中绑定跳转页参数(onclick location.href Eval)

    <asp:GridView runat="server" ID="gvCheckList" AutoGenerateColumns="false ...

  2. 关于easyui遇到的一些问题

    一.TreeGrid在IE浏览器中不能刷新 在创建TreeGrid的时候将method: 'get' 改成 method: 'post' , 然后再$('#ProductGrid').treegrid ...

  3. 提高ASP.NET应用程序性能的十大方法

    一.返回多个数据集 检查你的访问数据库的代码,看是否存在着要返回多次的请求.每次往返降低了你的应用程序的每秒能够响应请求的次数.通过在单个数据库请求中返回多个结果集,可以减少与数据库通信的时间,使你的 ...

  4. 怎么解决xp系统不能安装NET Framework4.0?

    第一步: 如果是XP系统: 1.开始——运行——输入cmd——回车——在打开的窗口中输入net stop WuAuServ 2.开始——运行——输入%windir% 3.在打开的窗口中有个文件夹叫So ...

  5. Redis各类型应用场景

    Redis的六种特性 l ,重要消息的,然后工作线程可以选择按 ret = r.zincrby("login:login_times", 1, uid) //那么如何获得登录次数最 ...

  6. HDU 2669

    题目大意: 已知线性方程ax+by=1; 输入a, b的值, 要求输出整数解x, y的值(输出x, y的最小整数解), 若没有解, 输出"sorry".   分析: 求线性方程的解 ...

  7. SQLSERVER跨数据库操作 ---- sp_addlinkedserver

    由于项目需要跨数据库进行相应的sql操作(这里遇到的是sqlserver的A库,到sqlserver的B库) sp_addlinkedserver [ @server = ] ' server ' [ ...

  8. mybatis的mapper中,实体非空检验问题

    因为项目变动,数据库需要删除一个字段,于是勤劳的我把项目中对应的实体属性也给弄掉了,可是没有弄彻底,mybatis里面的mapper没有管,当时感觉是选择性的插入: <if test=" ...

  9. 惯性导航之MEMS加速度计原理

    一 加速度计原理 1.1 加速度计由MEMS传感器与信号处理芯片组成. 1.2 MEMS加速度计工作原理 由上电容.中电容板(可移动).下电容板等组成:当加速度达到一定值后,中电容板会移动,与上.下电 ...

  10. redhat 安装 jdk1.7 问题

    redhat 安装 jdk 后出现 dl failure on line 685Error: failed /usr/local/jdk1.6.0_10/jre/lib/i386/client/lib ...