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]魔幻棋盘(二维线段树)的更多相关文章

  1. BZOJ2877 NOI2012魔幻棋盘(二维线段树)

    显然一个序列的gcd=gcd(其差分序列的gcd,序列中第一个数).于是一维情况直接线段树维护差分序列即可. 容易想到将该做法拓展到二维.于是考虑维护二维差分,查询时对差分矩阵求矩形的gcd,再对矩形 ...

  2. NOI 2012 魔幻棋盘 | 二维差分 + 二维线段树

    题目:luogu 2086 二维线段树,按套路差分原矩阵,gcd( x1, x2, ……, xn ) = gcd( xi , x2 - x1 , ……, xn - xn-1 ),必须要有一个原数 xi ...

  3. BZOJ2877 [Noi2012]魔幻棋盘

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  4. UVA 11297 线段树套线段树(二维线段树)

    题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要  不同的处理方式,非叶子形成的 ...

  5. POJ2155 Matrix二维线段树经典题

    题目链接 二维树状数组 #include<iostream> #include<math.h> #include<algorithm> #include<st ...

  6. HDU 1823 Luck and Love(二维线段树)

    之前只知道这个东西的大概概念,没具体去写,最近呵呵,今补上. 二维线段树 -- 点更段查 #include <cstdio> #include <cstring> #inclu ...

  7. poj 2155:Matrix(二维线段树,矩阵取反,好题)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17880   Accepted: 6709 Descripti ...

  8. poj 1195:Mobile phones(二维线段树,矩阵求和)

    Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14391   Accepted: 6685 De ...

  9. POJ 2155 Matrix (二维线段树)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17226   Accepted: 6461 Descripti ...

随机推荐

  1. GCC选项_-Wl,-soname 及 DT_NEEDED 的解释

    -Wl选项告诉编译器将后面的参数传递给链接器. -soname则指定了动态库的soname(简单共享名,Short for shared object name) soname的关键功能是它提供了兼容 ...

  2. 如何解决OpenStack创建虚拟机或删除虚拟机时一直处于deleting或者creating状态的问题(转载)

    原文地址:http://www.cnblogs.com/robertoji/p/4968280.html 在OpenStack使用时,有时候会遇到创建虚拟机或者删除虚拟机无法成功创建或者删除的时候,一 ...

  3. 【转】C语言正确使用extern关键字

    利用关键字extern,可以在一个文件中引用另一个文件中定义的变量或者函数,下面就结合具体的实例,分类说明一下. 一.引用同一个文件中的变量 #include<stdio.h> int f ...

  4. saltstack自动化运维系列⑥SaltStack实践安装配置HAproxy的Keepalived

    saltstack自动化运维系列⑥SaltStack实践安装配置HAproxy的Keepalived 安装配置Keepalived 1.编写功能模块 #创建keepalived目录# mkdir -p ...

  5. 一台电脑,两个及多个git账号配置

    1. 生成两[三]个ssh公钥私钥 方法参照:http://www.cnblogs.com/fanbi/p/7772812.html第三步骤 假定其中一个是id_rsa, 另一个时id_rsa_two ...

  6. jquery实现星级评分

    项目中遇到到实现星级评分,就用了这个插件 http://www.jq22.com/jquery-info291

  7. 实现div里的内容垂直居中

    ---恢复内容开始--- 在项目中我们会遇到这种情况,一个div的宽固定,里面的内容长度不定,不管是一行还是多行,都要垂直居中,有俩个实现方法: 1.使用absolute,top:50%,transf ...

  8. 关于java中生产者消费者模式的理解

    在说生产者消费者模式之前,我觉得有必要理解一下 Obj.wait(),与Obj.notify()方法.wait()方法是指在持有对象锁的线程调用此方法时,会释放对象锁,同时休眠本线程.notify() ...

  9. Inno Setup 系列之安装、卸载前检测进程运行情况并关闭相应进程

    需求 最近用 Inno Setup 做一个exe,可是在安装之前要停止正在运行的相应进程或者在卸载之前要停止正在运行的相应进程,可是发现它自身的方法不能满足要求,最后经过度娘的耐心帮助下终于在网上找到 ...

  10. java多线程快速入门(十三)

    死锁产生的原因(必须有两个线程.必须有多个锁.锁之间必须有引用的过程) package com.cppdy; class MyThread9 implements Runnable { private ...