[BZOJ2877][NOI2012]魔幻棋盘(二维线段树)
https://blog.sengxian.com/solutions/bzoj-2877
注意二维线段树的upd()也是一个O(log n)的函数(pushdown()应该也是但没写过)。
#include<cstdio>
#include<algorithm>
#define Ls (x<<1)
#define Rs (Ls|1)
#define Lson Ls,L,mid
#define Rson Rs,mid+1,R
#define lson ls[x],L,mid
#define rson rs[x],mid+1,R
#define rep(i,l,r) for (int i=(l); i<=(r); i++)
typedef long long ll;
using namespace std; const int N=,M=;
ll c,sm[M],a[N];
int n,m,x,y,T,nd,op,x1,x2,y1,y2,rt[N<<],ls[M],rs[M]; int F(int x,int y){ return (x-)*m+y; }
ll gcd(ll a,ll b){ return b ? gcd(b,a%b) : a; } void mdfy(int &x,int L,int R,int pos,ll k){
if (!x) x=++nd;
if (L==R){ sm[x]+=k; return; }
int mid=(L+R)>>;
if (pos<=mid) mdfy(lson,pos,k); else mdfy(rson,pos,k);
sm[x]=gcd(sm[ls[x]],sm[rs[x]]);
} void upd(int &x,int L,int R,int pos,int lp,int rp){
if (!x) x=++nd;
if (L==R){ sm[x]=gcd(sm[lp],sm[rp]); return; }
int mid=(L+R)>>;
if (pos<=mid) upd(lson,pos,ls[lp],ls[rp]); else upd(rson,pos,rs[lp],rs[rp]);
sm[x]=gcd(sm[ls[x]],sm[rs[x]]);
} void mdfx(int x,int L,int R,int x1,int y1,ll k){
if (L==R){ mdfy(rt[x],,m,y1,k); return; }
int mid=(L+R)>>;
if (x1<=mid) mdfx(Lson,x1,y1,k); else mdfx(Rson,x1,y1,k);
upd(rt[x],,m,y1,rt[Ls],rt[Rs]);
} ll quey(int x,int L,int R,int l,int r){
if (L==l && r==R) return sm[x];
int mid=(L+R)>>;
if (r<=mid) return quey(lson,l,r);
else if (l>mid) return quey(rson,l,r);
else return gcd(quey(lson,l,mid),quey(rson,mid+,r));
} ll quex(int x,int L,int R,int l,int r,int y1,int y2){
if (L==l && r==R) return quey(rt[x],,m,y1,y2);
int mid=(L+R)>>;
if (r<=mid) return quex(Lson,l,r,y1,y2);
else if (l>mid) return quex(Rson,l,r,y1,y2);
else return gcd(quex(Lson,l,mid,y1,y2),quex(Rson,mid+,r,y1,y2));
} int main(){
freopen("chess.in","r",stdin);
freopen("chess.out","w",stdout);
scanf("%d%d%d%d%d",&n,&m,&x,&y,&T); int r1=(n+)*+,r2=r1+;
rep(i,,n) rep(j,,m) scanf("%lld",&a[F(i,j)]);
rep(i,,n-) rep(j,,m-) mdfx(,,n,i,j,a[F(i+,j+)]-a[F(i+,j)]-a[F(i,j+)]+a[F(i,j)]);
rep(i,,n-) mdfy(rt[r1],,n,i,a[F(i+,y)]-a[F(i,y)]);
rep(i,,m-) mdfy(rt[r2],,m,i,a[F(x,i+)]-a[F(x,i)]);
while (T--){
scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2);
if (op==){
ll t1=(x1+x2) ? quey(rt[r1],,n,x-x1,x+x2-) : ;
ll t2=(y1+y2) ? quey(rt[r2],,m,y-y1,y+y2-) : ;
ll t3=((x1+x2)&&(y1+y2)) ? quex(,,n,x-x1,x+x2-,y-y1,y+y2-) : ;
printf("%lld\n",abs(gcd(gcd(t1,t2),gcd(t3,a[F(x,y)]))));
}else{
scanf("%lld",&c);
mdfx(,,n,x1-,y1-,c); mdfx(,,n,x1-,y2,-c);
mdfx(,,n,x2,y1-,-c); mdfx(,,n,x2,y2,c);
if (y1<=y && y2>=y) mdfy(rt[r1],,n,x1-,c),mdfy(rt[r1],,n,x2,-c);
if (x1<=x && x2>=x) mdfy(rt[r2],,m,y1-,c),mdfy(rt[r2],,m,y2,-c);
if (x1<=x && x2>=x && y1<=y && y2>=y) a[F(x,y)]+=c;
}
}
return ;
}
[BZOJ2877][NOI2012]魔幻棋盘(二维线段树)的更多相关文章
- BZOJ2877 NOI2012魔幻棋盘(二维线段树)
显然一个序列的gcd=gcd(其差分序列的gcd,序列中第一个数).于是一维情况直接线段树维护差分序列即可. 容易想到将该做法拓展到二维.于是考虑维护二维差分,查询时对差分矩阵求矩形的gcd,再对矩形 ...
- NOI 2012 魔幻棋盘 | 二维差分 + 二维线段树
题目:luogu 2086 二维线段树,按套路差分原矩阵,gcd( x1, x2, ……, xn ) = gcd( xi , x2 - x1 , ……, xn - xn-1 ),必须要有一个原数 xi ...
- BZOJ2877 [Noi2012]魔幻棋盘
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- UVA 11297 线段树套线段树(二维线段树)
题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要 不同的处理方式,非叶子形成的 ...
- POJ2155 Matrix二维线段树经典题
题目链接 二维树状数组 #include<iostream> #include<math.h> #include<algorithm> #include<st ...
- HDU 1823 Luck and Love(二维线段树)
之前只知道这个东西的大概概念,没具体去写,最近呵呵,今补上. 二维线段树 -- 点更段查 #include <cstdio> #include <cstring> #inclu ...
- poj 2155:Matrix(二维线段树,矩阵取反,好题)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17880 Accepted: 6709 Descripti ...
- poj 1195:Mobile phones(二维线段树,矩阵求和)
Mobile phones Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 14391 Accepted: 6685 De ...
- POJ 2155 Matrix (二维线段树)
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17226 Accepted: 6461 Descripti ...
随机推荐
- ROS 错误之 [rospack] Error: package 'beginner_tutorials' not found
ubuntu 下面情况处理 $ cd $gedit .bashrc 再后面加入两行 source /opt/ros/indigo/setup.bash source /home/lv/catkin_w ...
- LOJ 2567: 洛谷 P3643: bzoj 4584: 「APIO2016」划艇
题目传送门:LOJ #2249. 题意简述: 有 \(n\) 个位置,第 \(i\) 个位置可以填在 \([a_i,b_i]\) (\(1\le a_i\le b_i\le 10^9\))之间的整数, ...
- linux统计某个特定文件名的大小总和【原创】
[hch@EAISRVBJ2 log]$find ./ -name "test_chs_00*"|xargs du -ck|grep total|awk 'BEGIN{sum=0} ...
- spring事物的传播行为及隔离
关于@Transactional注解: 添加事务注解1.使用 propagation 指定事务的传播行为, 即当前的事务方法被另外一个事务方法调用时如何使用事务, 默认取值为 REQUIRED, 即使 ...
- win7 X64系统上 PL/SQL不能识别Oracle实例
电脑系统为Win7 64位,安装的PLSql为64位,安装的Oracle客户端为运行时类型的,应该为32位客户端 电脑上之前安装的32位toad可以识别Oracle实例 在系统添加了oracle_ho ...
- Mac 安装 JDK
1.访问Oracle官网 http://www.oracle.com,下载 JDK 2.安装JDK 解压 1 中下载的压缩包,在Finder下载目录中双击安装. 或者命令行安装,详见:http://w ...
- web----ssl通信
ssl通信 https://www.cnblogs.com/zhengah/p/5007753.html
- Mysql在master上查看有哪些slave
mysql> select * from information_schema.processlist as p where p.command = 'Binlog Dump'; 或 mysql ...
- thinkphp注册验证
在model中新建一个UserModel //覆盖原本的设置 //一次性获得全部验证错误 protected $patchValidate = true; //实现表单项目验证 //通过重写父类属性_ ...
- Python之禅的翻译和解释
The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit ...