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. MySQL ERROR 1005: Can't create table (errno: 150)的错误解决办法

    在mysql 中建立引用约束的时候会出现MySQL ERROR 1005: Can't create table (errno: 150)的错误信息结果是不能建立 引用约束. 出现问题的大致情况 1. ...

  2. Javascript学习笔记1 javascript的特点

    ..对于网页而言,Javascript无处不在,对于英语不好的人它简直是噩梦般的存在,但形式所逼,今天开始着手学习!希望自己能坚持下去.从什么地方着手,我的目标是从大处着眼,从应用着眼,不抠细节,反正 ...

  3. Java—图形处理

    抽象窗口化工具(AWT)为图形用户界面编程提供API编程接口,使得Java可以提供较好的图形用户界面. AWT把图形处理分为两个层次:一是处理原始图形,这一层较原始,图形直接以点.线和面的形式画到界面 ...

  4. 对象列表转换为DataTable或DataTable转换为对象列表.

    /**********************************************************************************/ // 说明: 数据转换工具. ...

  5. 一个crackme的分析

    是看雪合集的一个,因为老师让我们多练习,所以我就找了个crackme来练习 http://images2015.cnblogs.com/blog/638600/201612/638600-201612 ...

  6. java连接sql问题

    1.No suitable driver found for Jdbc: 1)确保​jdbc:sqlserver://localhost;user=sa;password=123456;databas ...

  7. android两种基本联网方式与一种第三方开源项目的使用

    安卓请求网络的三种方式 在请求网络的时候一般常用的提交方式是post或者get请求,post请求安全,传输大小无限制,但是代码量多些,get请求是浏览器有大小限制,用户提交的信息在浏览器的地址栏显示出 ...

  8. usb端口号绑定

    由于ubuntu USB设备号为从零开始依次累加,所以多个设备每次开机后设备号不固定,机器人每次开机都要蛋疼的按顺序插, 在网上找到一种方法:udev的规则 udev的规则说明,可以参考博客说明:ht ...

  9. 用JQuery Validate框架,在IE8下验证报错问题解决

    网站后台用了JQuery Validate框架,版本是jQuery Validation Plugin 1.8.1 因为用的时间比较久了,一直没有更新新版本. 最近公司信息录入员有调整,没有IE11浏 ...

  10. 解决iis+php+mysql访问速度慢的方法

    IIS7.5网站访问PHP响应慢的原因原因是PHP5.3以上支持IPv6协议,但是大家的服务器未使用IPv6,当访问PHP的时候会连接MySQL的地址为localhost,系统会会先用IPv6连接,但 ...