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 ...
随机推荐
- HEAD FIRST HTML & CSS学习笔记1
一.指定媒体类型=指定显示设备的类型 P400 有两种方式指定媒体类型: a. 直接在<link>标签中加属性media,例: <link href="print.css ...
- Python笔记总结week3
Set集合: 无序,不重复的序列 a. 创建 se = {"123,"456" } print(type(se)) #创建集合方式 s1 = se = {"12 ...
- android .9图的作用
参考:http://www.cnblogs.com/lianghui66/archive/2013/01/08/2850581.html .9图的介绍 1.这种格式的图片是Android平台上一种被拉 ...
- TypeError: window.open is not a function
想必大家现在都已经到家了,而苦逼的我还要坐在办公室混拿微薄的工资,技不如人,平常不努力给自己充电,年终一毛钱都没多给.不说这扫兴的话题了,在这给同样在苦逼坚守岗位的同志们节日的问候,新的一年,好运连连 ...
- 学习winform第三方界面weiFenLuo.winFormsUI.Docking.dll
控件dockpanel中提供了几个可用的类, 重要的有两个, 一是DockPanel, 一是DockContent, DockPanel是从panel继承出来的, 用于提供可浮动的dock的子窗口进行 ...
- <java基础学习>01环境变量配置
安装完JDK开始配置系统环境变量,在path变量里面添加java的bin目录 方法二: 配置完成后 在命令下输入javac查看是否配置成功 第一个java程序 hello world! class H ...
- Linq to entities 学习笔记
Linq to entities ---提供语言集成查询支持用于在概念模型中定义的实体类型. 首先可以根据http://msdn.microsoft.com/en-us/data/jj206878该 ...
- 过滤器Filter
实现Filter接口:
- HOJ 1001: A+B; 1002: A+B+C
两道水题,用来熟悉 HOJ 的提交系统. 1001:输入两个整数 A, B (0 <= A,B <= 10),输出 A+B. #include <iostream> using ...
- linux命令每日一练习-tail
tail 是查看文件的末尾 tail -n 5*** 显示文件×××的最后5行 tail -n +5 ××× 显示文件×××从第5行开始的内容 tail -f *** 监视文件×××的末尾.循环展示