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. scn 时间

    Scn转换成时间: select to_char(scn_to_timestamp(3998591352171),'YYYY-MM-DD HH24:MI:SS') from dual: 时间转换成sc ...

  2. asp.net core 2.0 api ajax跨域问题

    API配置: services.AddCors(options => { options.AddPolicy("any", builder => { builder.W ...

  3. 篮球弹起问题(for循环)

  4. Eclipse通过jdbc连接sqlserver2008数据库的两种方式

    数据库登录身份验证方式有两种     其中服务器名称即为安装SQLServer2008的电脑,充当数据库服务器,在笔者这里就是自己的电脑名称. 身份验证方式有两种:windows身份验证和SQLSer ...

  5. vue2之对象属性的监听

    对象属性监听的两种方法: 1.普通的watch data() { return { frontPoints: 0 } }, watch: { frontPoints(newValue, oldValu ...

  6. python3的unittest中使用test suite(测试套件)执行指定测试用例

    示例代码 module.py class baidumodule(): def __init__(self,driver,): self.dr = driver #不能在类中再次导入webdriver ...

  7. MySQL学习笔记:一道group by+group_concat解决的小问题

    闲来无事,逛逛V2EX发现一道MySQL数据库题目,原题如下: 遂打开很长一段时间都没用过SQLyog,噗呲噗呲的干起活来…… 建测试表: CREATE TABLE test_001 ( id INT ...

  8. 步步为营-17-FileStream-文件加密/解密

    以前使用的File是操作小的文本文件,用的并不常见,FileStream(操作字节),可以操作所有格式的文件,用途较广泛 下面做一个通过文件流给文件加密解密的小软件. using System; us ...

  9. WaitForMultipleObjects返回0xffffffff

    DWORD ret; ; HANDLE handle[THREAD_NUM]; ; i < THREAD_NUM; i++) handle[i] = (HANDLE)_beginthreadex ...

  10. JVM启动过程 类加载器

    下图来自:http://blog.csdn.net/jiangwei0910410003/article/details/17733153 package com.test.jvm.common; i ...