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. html/css小练习2

    效果图:

  2. 前端面试题2016--CSS

    介绍一下标准的CSS的盒子模型?低版本IE的盒子模型有什么不同的? (1)有两种,IE 盒子模型.W3C 盒子模型:(2)盒模型:内容(content).填充(padding).边界(margin). ...

  3. Python【7】-数据分析准备

    一.经常用到的python库: Numpy:Python科学计算的基础包: pandas:提供了能使我们快捷的处理结构化数据的大量数据结构和函数: matplotlib:用于绘制数据图表的python ...

  4. Laravel框架 mysql 数据库 —— 基本使用

    增删改查 配置完数据库连接,就可以使用DB类进行查询了. 查询 $results = DB::select('select * from users where id = ?', array(1)); ...

  5. html5之canvas画图基础

    HTML5+CSS3的好处是,你可以编写一个页面分别用于不同的平台,只需要设置不同的css样式就可以了,现在基本主流浏览器都支持全新的HTML5和CSS3,因为它的跨平台开发.因为是原生代码所以它的页 ...

  6. JavaScript 开发的45个经典技巧

    JavaScript是一个绝冠全球的编程语言,可用于Web开发.移动应用开发(PhoneGap.Appcelerator).服务器端开发(Node.js和Wakanda)等等.JavaScript还是 ...

  7. 最少clock

    var elClock = document.getElementById("clock");var getTime = function(){ var _ = ['00','01 ...

  8. WireShark网络性能分析

    最近生产上出现一个性能问题,表现为:行情延时5s左右.从log一路追查下去,发现是我们自己写的一个行情网关(部署在xx.xx.xx.132)<->第三方的中转网关(部署在xx.xx.xx. ...

  9. js图片拖放原理(很简单,不是框架,入门基础)

    <html> <meta> <script src='jquery-1.8.3.min.js'></script> <script> /* ...

  10. java常用注释

    @see 加入超链接 @see 类名 @see 完整类名 @see 完整类名#方法名 @version 版本信息 @author 作者信息 @param 参数名 说明 @return 说明 @exce ...