2877: [Noi2012]魔幻棋盘 - BZOJ

时间:2022-09-02 12:35:09

Description
Input

第一行为两个正整数N,M,表示棋盘的大小。 第二行为两个正整数X,Y,表示棋盘守护者的位置。 第三行仅有一个正整数T,表示棋盘守护者将进行次操作。 接下来N行,每行有M个正整数,用来描述初始时棋盘上每个位置的数。 接下来T行,按操作的时间顺序给出T次操作。每行描述一次操作,以一个数字0或1开头: 若以数字0开头,表示此操作为询问,随后会有四个非负整数x1,y1,x2,y2,表示询问的区域是以棋盘守护者的位置为基础向上扩展x1行,向下扩展y1行,向左扩展x2列,向右扩展y2列得到的矩形区域(详见样例)。 若以数字1开头,表示此操作为修改,随后会有四个正整数x1,y1,x2,y2和一个整数c,表示修改区域的上、下边界分别为第x1,x2行,左、右边界分别为第y1,y2列(详见样例),在此矩形区域内的所有数统一加上c(注意c可能为负数)。
Output

对于每次询问操作,每行输出一个数,表示该区域内所有数的最大公约数。
Sample Input
2 2
1 1
4
6 12
18 24
0 0 0 1 0
1 1 1 1 2 6
1 2 1 2 2 6
0 0 0 1 1

Sample Output
6 6

一开始觉得直接放在一个二维线段树上,但是太麻烦了(打了20多个if,没有力气debug)

想了一晚上,果断改成两个一维的和一个二维的,好打多了,早上改了一下就A了

首先按点(x,y)把棋盘化成4个部分,然后就相当于只要得到前缀gcd,所以横着差分一下,竖着差分一下,然后把4个矩形拼在一起就变成了正解里的那个奇怪的矩阵

第一次打二维线段树

 const
maxn=;
type
node=record
l,r,lc,rc:longint;
a:int64;
end;
var
a,b:array[..maxn]of int64;
f,f2:array[..maxn*]of node;
n,m,t,x,y,tot,cnt,ll,rr,root1,root2:longint; function calc(a,b:longint):longint;
begin
exit((a-)*m+b);
end; function gcd(a,b:int64):int64;
begin
if b= then exit(a);
exit(gcd(b,a mod b));
end; procedure new(x,y,z:longint);
begin
f2[x].a:=gcd(abs(f2[y].a),abs(f2[z].a));
if f2[x].l=f2[x].r then exit;
new(f2[x].lc,f2[y].lc,f2[z].lc);
new(f2[x].rc,f2[y].rc,f2[z].rc);
end; procedure build2(l,r:longint);
var
now,mid:longint;
begin
if l>r then exit;
inc(cnt);now:=cnt;
f2[now].l:=l;f2[now].r:=r;
if l=r then
begin
if ll=rr then f2[now].a:=b[calc(ll,l)];
exit;
end;
mid:=(l+r)>>;
f2[now].lc:=cnt+;
build2(l,mid);
f2[now].rc:=cnt+;
build2(mid+,r);
if ll=rr then f2[now].a:=gcd(abs(f2[f2[now].lc].a),abs(f2[f2[now].rc].a));
end; procedure build(l,r:longint);
var
now,mid:longint;
begin
if l>r then exit;
inc(tot);now:=tot;
f[now].l:=l;f[now].r:=r;
if l=r then
begin
f[now].a:=cnt+;
ll:=l;rr:=r;
build2(,m-);
exit;
end;
mid:=(l+r)>>;
f[now].lc:=tot+;
build(l,mid);
f[now].rc:=tot+;
build(mid+,r);
f[now].a:=cnt+;
ll:=l;rr:=r;
build2(,m-);
new(f[now].a,f[f[now].lc].a,f[f[now].rc].a);
end; function get(now,l,r:longint):int64;
var
mid:longint;
begin
if (f2[now].l>=l) and (f2[now].r<=r) then exit(abs(f2[now].a));
mid:=(f2[now].l+f2[now].r)>>;
get:=;
if l<=mid then get:=gcd(get(f2[now].lc,l,r),get);
if r>mid then get:=gcd(get(f2[now].rc,l,r),get);
end; function get(now,x1,y1,x2,y2:longint):int64;
var
mid:longint;
begin
if (x1>y1) or (x2>y2) then exit();
if (f[now].l>=x1) and (f[now].r<=y1) then exit(get(f[now].a,x2,y2));
get:=;mid:=(f[now].l+f[now].r)>>;
if x1<=mid then get:=gcd(get(f[now].lc,x1,y1,x2,y2),get);
if y1>mid then get:=gcd(get(f[now].rc,x1,y1,x2,y2),get);
end; procedure new(x,y,z,k:longint);
var
mid:longint;
begin
f2[x].a:=gcd(abs(f2[y].a),abs(f2[z].a));
if f2[x].l=f2[x].r then exit;
mid:=(f2[x].l+f2[x].r)>>;
if k<=mid then new(f2[x].lc,f2[y].lc,f2[z].lc,k)
else new(f2[x].rc,f2[y].rc,f2[z].rc,k);
end; procedure add(now,x:longint;c:int64);
var
mid:longint;
begin
if f2[now].l=f2[now].r then
begin
inc(f2[now].a,c);
exit;
end;
mid:=(f2[now].l+f2[now].r)>>;
if x<=mid then add(f2[now].lc,x,c)
else add(f2[now].rc,x,c);
f2[now].a:=gcd(abs(f2[f2[now].lc].a),abs(f2[f2[now].rc].a));
end; procedure add(now,x,y:longint;c:int64);
var
mid:longint;
begin
if (x<) or (x>=n) or (y<) or (y>=m) then exit;
if f[now].l=f[now].r then
begin
add(f[now].a,y,c);
exit;
end;
mid:=(f[now].l+f[now].r)>>;
if x<=mid then add(f[now].lc,x,y,c)
else add(f[now].rc,x,y,c);
new(f[now].a,f[f[now].lc].a,f[f[now].rc].a,y);
end; procedure main;
var
i,j,k,x1,y1,x2,y2:longint;
c:int64;
begin
read(n,m,x,y,t);
for i:= to n do
for j:= to m do
read(a[calc(i,j)]);
for i:= to n- do
for j:= to m- do
b[calc(i,j)]:=a[calc(i,j)]+a[calc(i+,j+)]-a[calc(i,j+)]-a[calc(i+,j)];
build(,n-);
ll:=rr+;
root1:=cnt+;
build2(,n);
root2:=cnt+;
build2(,m);
for i:= to n do
if i=x then add(root1,x,a[calc(x,y)])
else
if i<x then add(root1,i,a[calc(i,y)]-a[calc(i+,y)])
else add(root1,i,a[calc(i,y)]-a[calc(i-,y)]);
for i:= to m do
if i=y then add(root2,y,a[calc(x,y)])
else
if i<y then add(root2,i,a[calc(x,i)]-a[calc(x,i+)])
else add(root2,i,a[calc(x,i)]-a[calc(x,i-)]);
for i:= to t do
begin
read(k,x1,y1,x2,y2);
if k= then writeln(gcd(gcd(get(,x-x1,x+x2-,y-y1,y+y2-),get(root1,x-x1,x+x2)),get(root2,y-y1,y+y2)))
else
begin
read(c);
if (x1<=x) and (x2>=x) and (y1<=y) and (y2>=y) then
begin
add(root1,x,c);
add(root2,y,c);
end;
if (x1<=x) and (x2>=x) then
begin
if (y1<=y) and (y1>) then add(root2,y1-,-c);
if y1>y then add(root2,y1,c);
if (y2>=y) and (y2<m) then add(root2,y2+,-c);
if y2<y then add(root2,y2,c);
end;
if (y1<=y) and (y2>=y) then
begin
if (x1<=x) and (x1>) then add(root1,x1-,-c);
if x1>x then add(root1,x1,c);
if (x2>=x) and (x2<n) then add(root1,x2+,-c);
if x2<x then add(root1,x2,c);
end;
add(,x1-,y1-,c);
add(,x1-,y2,-c);
add(,x2,y2,c);
add(,x2,y1-,-c);
end;
end;
end; begin
main;
end.

2877: [Noi2012]魔幻棋盘 - BZOJ的更多相关文章

  1. BZOJ2877:&lbrack;NOI2012&rsqb;魔幻棋盘

    浅谈树状数组与主席树:https://www.cnblogs.com/AKMer/p/9946944.html 题目传送门:https://lydsy.com/JudgeOnline/problem. ...

  2. NOI2012 魔幻棋盘

    http://www.lydsy.com/JudgeOnline/problem.php?id=2877 二维线段树. 好恶...... B类数据: 棋盘是一维的. 我们有一个结论: $gcd(a_{ ...

  3. 【bzoj2877】 Noi2012—魔幻棋盘

    http://www.lydsy.com/JudgeOnline/problem.php?id=2877 (题目链接) 题意 一个${n*m}$的矩阵,维护两个操作:给任意子矩阵${+val}$:问某 ...

  4. BZOJ2877 &lbrack;Noi2012&rsqb;魔幻棋盘

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

  5. 题解 洛谷 P2086 【&lbrack;NOI2012&rsqb;魔幻棋盘】

    先考虑只有一维的情况,要求支持区间加和求区间 \(\gcd\),根据 \(\gcd\) 的性质,发现: \[ \gcd(a_1,a_2,a_3,\ldots a_n)=\gcd(a_i,a_2-a_1 ...

  6. 数据结构(二维线段树,差分): NOI2012 魔幻棋盘

    貌似想复杂了…… #include <iostream> #include <cstring> #include <cstdio> #define mid ((l+ ...

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

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

  8. &lbrack;BZOJ2877&rsqb;&lbrack;NOI2012&rsqb;魔幻棋盘&lpar;二维线段树&rpar;

    https://blog.sengxian.com/solutions/bzoj-2877 注意二维线段树的upd()也是一个O(log n)的函数(pushdown()应该也是但没写过). #inc ...

  9. 【NOI2012】魔幻棋盘

    Description 将要读二年级的小 Q 买了一款新型益智玩具——魔幻棋盘,它是一个N行M列的网格棋盘,每个格子中均有一个正整数.棋盘守护者在棋盘的第X行Y列(行与列均从1开始编号) 并且始终不会 ...

随机推荐

  1. 新浪微博客户端&lpar;36&rpar;-自定义带placeholder的TextView

    iOS 上自带的UITextView竟然不能设置placeholder,但是UITextView却可以,我也真是醉了.没办法了,自己写一个 DJTextView.h #import <UIKit ...

  2. Linux&sol;Ubuntu sudo不用输入密码的方法

    通常我们并不以root身份登录,但是当我们执行某些命令 (command)时需要用到root权限,我们通常都是用"sudo command"来执行command.由于使用Ubunt ...

  3. 配置DruidDataSource参考(com&period;alibaba&period;druid&period;pool&period;DruidDataSource)

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-met ...

  4. Retrofit分析-漂亮的解耦套路

    没耐心自己分析源码的同学,还可以参考Stay录制的视频版 Retrofit分析-漂亮的解耦套路(视频版) 万万没想到Retrofit会这么火,在没看源码之前,我简单的认为是因为它跟OkHttp同出一源 ...

  5. MYSQL 优化建议

    转自 http://coolshell.cn/articles/1846.html MYSQL 优化建议20条 1. 为查询缓存优化你的查询 大多数的MySQL服务器都开启了查询缓存.这是提高性最有效 ...

  6. STL中主要的算法&lpar;一&rpar;

    一.replace() 替换算法将指定元素值替换为新值,使用原型例如以下,将迭代器[first,last)中值为old_value的元素所有替换为new_value值. 函数原型: template  ...

  7. Mac系统占用空间大、空间不够、查看系统文件大小分布

    最近电脑老提示空间不够,甚是心烦,决定研究下,为啥空间这么快就花完了. 如图,256的空间,就剩下几个G了,其中最大头的系统占用:160G,占比60%多,我勒个擦... 正常情况下:我们可以点击管理, ...

  8. VMware虚拟机Linux增加磁盘空间的扩容操作

    转载自点击打开链接 用VMwareware虚拟机安装的Red Hat Enterprise Linux系统剩余空间不足,造成软件无法正常安装.如果重新装一遍系统就需要重新配置好开发环境和软件的安装配置 ...

  9. MySQL基础之 外键参照讲解

    外键: 定义:如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表. 作用:外键是用来实现参照完整性的,不同的外键约束方式将可以是两张表紧密的结合起来.比如修改或者删除 ...

  10. iOS开发技巧 - 使用UISlider来调整值的范围

    (Swift) import UIKit class ViewController: UIViewController { var slider: UISlider! func sliderValue ...