codeforces 341d (树状数组)
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 (树状数组)的更多相关文章
- HDU 3333 | Codeforces 703D 树状数组、离散化
HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333 这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序.这里我们需要离散化 ...
- CodeForces 396C 树状数组 + DFS
本主题开始看到以为段树或树状数组,但是,对于一个节点的有疑问的所有子节点的加权,这一条件被视为树的根,像 然后1号是肯定在第一层中,然后建立一个单向侧倒查,然后记录下来 其中每个节点 层,终于 两个节 ...
- Codeforces 276E(树状数组)
题意:一棵树有n个节点,1是根节点,根节点的子节点是单链,然后如今有两种操作0 v x d表示距离节点v为d的节点权值都加x,操作1 v问v节点的权值,初始节点权值都是0. 题解:看了别人的题解才会的 ...
- Tokitsukaze and Strange Rectangle CodeForces - 1191F (树状数组,计数)
大意: 给定$n$个平面点, 定义集合$S(l,r,a)$表示横坐标$[l,r]$纵坐标$[a,\infty]$内的所有点. 求可以得到多少种不同的集合. 从上往下枚举底层最右侧点, 树状数组统计贡献 ...
- codeforces 629D 树状数组+LIS
题意:n个圆柱形蛋糕,给你半径 r 和高度 h,一个蛋糕只能放在一个体积比它小而且序号小于它的蛋糕上面,问你这样形成的上升序列中,体积和最大是多少 分析:根据他们的体积进行离散化,然后建树状数组,按照 ...
- Encryption (hard) CodeForces - 958C3 (树状数组)
大意: 给定序列$a$, 要求将$a$分成$k$个非空区间, 使得区间和模$p$的和最小, 要求输出最小值. $k$和$p$比较小, 直接暴力$dp$, 时间复杂度是$O(nklogp)$, 空间是$ ...
- codeforces 597C (树状数组+DP)
题目链接:http://codeforces.com/contest/597/problem/C 思路:dp[i][j]表示长度为i,以j结尾的上升子序列,则有dp[i][j]= ∑dp[i-1][k ...
- Codeforces 597C. Subsequences (树状数组+dp)
题目链接:http://codeforces.com/contest/597/problem/C 给你n和数(1~n各不同),问你长为k+1的上升自序列有多少. dp[i][j] 表示末尾数字为i 长 ...
- Codeforces Round #365 (Div. 2) D. Mishka and Interesting sum (离线树状数组+前缀xor)
题目链接:http://codeforces.com/contest/703/problem/D 给你n个数,m次查询,每次查询问你l到r之间出现偶数次的数字xor和是多少. 我们可以先预处理前缀和X ...
随机推荐
- 环境jdk、编码不一致造成的项目报错
一个项目在eclipse 中可以运行 , 到另一个eclipse 中不能运行,多是因为jdk过低.包没有引人.环境jdk.编码不一致造成的.或者是因为编译文件在另一个环境里跟JDK等 不匹配. 解决办 ...
- Xcode模拟器不显示SDK版本,反而显示设备ID的解决办法
今天在应用程序中修改了Xcode app 的名称,结果导致Xcode模拟器不显示SDK版本,反而显示设备ID了,感觉特别的忧伤......如图: 进到Xcode->window->Devi ...
- guava学习--Function、Predicate
Function用于同步转换. Predicate用于过滤. import java.util.Collection; import java.util.Iterator; import java.u ...
- 禁止浏览.htaccess文件
很多黑客会攻击和利用.htaccess做网站跳转,所以保护好.htaccess文件尤为重要. 在apache的httpd.conf的配置文件中 默认是已经设置了禁止对.htaccess的访问,截取相关 ...
- nginx 页面乱码问题
在配置nginx时常常遇到网页乱码的问题如图: 这时需要在server段里面添加两行: default_type 'text/html'; charset utf-8; 然后执行测试 重启操作 ng ...
- js2
1.JS的三种输出方式: alert("");console.log("");document.write(""); 2.流程控制语句: a ...
- Linux学习 :字符设备框架
一.系统功能框架: U-boot : 启动内核 linux kernel: 启动应用 应用: open,read,write 都是通过C库实现,汇编就相当于swi val,引发中断,通过系统调用接口在 ...
- 重叠I/O模型
一. 重叠I/O的概念当调用ReadFile和WriteFile时,如果最后一个参数lpOverlapped设置为NULL,那么线程就阻塞在这里,直到读写完指定的数据后,它们才返回.这样在读写大文件的 ...
- javap查看class文件
通过JVM编译java文件生成class字节码文件,很多时候很想用工具打开看看,目前还不清楚哪一个软件专门查看class文件的,但是通过windows下的javap命令可以查看详细的class文件 S ...
- Object方法equals、hashCode
java知识背景: 1)hashCode()方法返回的是Jvm的32位地址 2)==比较的是对象在jvm中的地址 3)Object的equals()比较的就是jvm物理地址 4)比较2个对象使用equ ...