题解

代码7.1KB,人傻代码长

恶心死我了这代码真的把我写恶心了= =

想一想就知道这个东西……维护到中心的差分,然后用二维线段树维护一下矩形的gcd

嗯,我说完了,你写吧。

首先这个二维线段树的单点修改啊,要把第一维遍历过的节点也修改了,还不能直接修改,需要把第一维的左右子树里套的线段树拿出来合并

然后这个差分啊,我为了好搞一点,拆成了9个矩阵,也就是

中心,中心上方,中心下方,中心左方,中心右方,左上,右上,左下,右下

每次和矩形取一个交集

给中心左右的矩形加的时候需要给这个矩形的上下都差分上

给中心的方块加的时候需要给这个矩形的四个角也差分上

算了我讲不明白了,也不想画图了

de了好长时间的bug,颓颓颓颓颓

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define enter putchar('\n')
#define space putchar(' ')
#define MAXN 500005
//#define ivorysi
using namespace std;
typedef long long int64;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 - '0' + c;
c = getchar();
}
res = res * f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) out(x / 10);
putchar('0' + x % 10);
} int N,M,X,Y,T,Rt,Ncnt,tot;
int64 D[MAXN],V,A[MAXN],num[MAXN];
struct Matrix {
int X1,X2,Y1,Y2;
}MK[15];
struct node {
int lc,rc,rt;
int64 G;
}tr[MAXN * 70];
int64 gcd(int64 a,int64 b) {
return b == 0 ? a : gcd(b,a % b);
}
int c(int x,int y) {
return (x - 1) * M + y;
} void update(int u) {
tr[u].G = gcd(abs(tr[tr[u].lc].G),abs(tr[tr[u].rc].G));
}
void build(int& u,int t,int L,int R) {
u = ++Ncnt;
if(L == R) {
tr[u].G = D[c(t,L)];
return;
}
int mid = (L + R) >> 1;
build(tr[u].lc,t,L,mid);
build(tr[u].rc,t,mid + 1,R);
update(u);
}
void Union(int &u,int Lu,int Ru,int L,int R) {
u = ++Ncnt;
if(L == R) {
tr[u].G = gcd(abs(tr[Lu].G),abs(tr[Ru].G));
return;
}
int mid = (L + R) >> 1;
Union(tr[u].lc,tr[Lu].lc,tr[Ru].lc,L,mid);
Union(tr[u].rc,tr[Lu].rc,tr[Ru].rc,mid + 1,R);
update(u);
}
void Build(int &u,int L,int R) {
u = ++Ncnt;
if(L == R) {
build(tr[u].rt,L,1,M);
return;
}
int mid = (L + R) >> 1;
Build(tr[u].lc,L,mid);
Build(tr[u].rc,mid + 1,R);
Union(tr[u].rt,tr[tr[u].lc].rt,tr[tr[u].rc].rt,1,M);
}
void modify(int u,int L,int R,int p,int64 v) {
if(L == R) {tr[u].G += v;return;}
int mid = (L + R) >> 1;
if(p <= mid) modify(tr[u].lc,L,mid,p,v);
else modify(tr[u].rc,mid + 1,R,p,v);
update(u);
}
void Union_modify(int u,int Lu,int Ru,int L,int R,int p) {
if(L == R) {
tr[u].G = gcd(abs(tr[Lu].G),abs(tr[Ru].G));
return;
}
int mid = (L + R) >> 1;
if(p <= mid) Union_modify(tr[u].lc,tr[Lu].lc,tr[Ru].lc,L,mid,p);
else Union_modify(tr[u].rc,tr[Lu].rc,tr[Ru].rc,mid + 1,R,p);
update(u);
}
void Modify(int u,int L,int R,int x,int y,int64 v) { if(L == R) {modify(tr[u].rt,1,M,y,v);return;}
int mid = (L + R) >> 1;
if(x <= mid) Modify(tr[u].lc,L,mid,x,y,v);
else Modify(tr[u].rc,mid + 1,R,x,y,v);
Union_modify(tr[u].rt,tr[tr[u].lc].rt,tr[tr[u].rc].rt,1,M,y);
return;
}
int64 query(int u,int L,int R,int ql,int qr) {
if(L == ql && R == qr) return abs(tr[u].G);
int mid = (L + R) >> 1;
if(qr <= mid) return query(tr[u].lc,L,mid,ql,qr);
else if(ql > mid) return query(tr[u].rc,mid + 1,R,ql,qr);
else return gcd(query(tr[u].lc,L,mid,ql,mid),query(tr[u].rc,mid + 1,R,mid + 1,qr));
}
int64 Query(int u,int L,int R,Matrix t) {
if(L == t.X1 && R == t.X2) return query(tr[u].rt,1,M,t.Y1,t.Y2);
int mid = (L + R) >> 1;
if(t.X2 <= mid) return Query(tr[u].lc,L,mid,t);
else if(t.X1 > mid) return Query(tr[u].rc,mid + 1,R,t);
else return gcd(Query(tr[u].lc,L,mid,(Matrix){t.X1,mid,t.Y1,t.Y2}),
Query(tr[u].rc,mid + 1,R,(Matrix){mid + 1,t.X2,t.Y1,t.Y2}));
}
void Init() {
read(N);read(M);read(X);read(Y);read(T);
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= M ; ++j) {
read(D[c(i,j)]);A[c(i,j)] = D[c(i,j)];
}
}
V = D[c(X,Y)];
for(int i = 1 ; i <= N ; ++i) {
for(int j = 1 ; j <= Y - 1 ; ++j) {
D[c(i,j)] = D[c(i,j)] - D[c(i,j + 1)];
}
for(int j = M ; j >= Y + 1 ; --j) {
D[c(i,j)] = D[c(i,j)] - D[c(i,j - 1)];
}
}
for(int j = 1 ; j <= M ; ++j) {
for(int i = 1 ; i <= X - 1 ; ++i) {
D[c(i,j)] = D[c(i,j)] - D[c(i + 1,j)];
}
for(int i = N ; i >= X + 1 ; --i) {
D[c(i,j)] = D[c(i,j)] - D[c(i - 1,j)];
}
}
Build(Rt,1,N);
MK[++tot] = (Matrix){X,X,1,Y - 1};
MK[++tot] = (Matrix){X,X,Y + 1,M};
MK[++tot] = (Matrix){1,X - 1,Y,Y};
MK[++tot] = (Matrix){X + 1,N,Y,Y};
MK[++tot] = (Matrix){1,X - 1,1,Y - 1};
MK[++tot] = (Matrix){1,X - 1,Y + 1,M};
MK[++tot] = (Matrix){X + 1,N,1,Y - 1};
MK[++tot] = (Matrix){X + 1,N,Y + 1,M};
}
int64 Calc(Matrix a,Matrix b) {
Matrix c;
c.X1 = max(a.X1,b.X1);c.X2 = min(a.X2,b.X2);
c.Y1 = max(a.Y1,b.Y1);c.Y2 = min(a.Y2,b.Y2);
if(c.X1 > c.X2 || c.Y1 > c.Y2) return 0;
return Query(Rt,1,N,c);
}
void Add_pos(int x,int y,int64 v) {
if(x < 1 || x > N || y < 1 || y > M) return;
Modify(Rt,1,N,x,y,v);
D[c(x,y)] += v;
}
void Add(Matrix a,Matrix b,int64 v) {
Matrix c;
c.X1 = max(a.X1,b.X1);c.X2 = min(a.X2,b.X2);
c.Y1 = max(a.Y1,b.Y1);c.Y2 = min(a.Y2,b.Y2);
if(c.X1 > c.X2 || c.Y1 > c.Y2) return;
if(c.X1 == X) {
if(c.Y1 <= Y) {
Add_pos(c.X1,c.Y2,v);Add_pos(c.X1,c.Y1 - 1,-v);
Add_pos(c.X1 - 1,c.Y1 - 1,v);Add_pos(c.X1 + 1,c.Y1 - 1,v);
Add_pos(c.X1 - 1,c.Y2,-v);Add_pos(c.X1 + 1,c.Y2,-v);
}
else {
Add_pos(c.X1,c.Y1,v);Add_pos(c.X1,c.Y2 + 1,-v);
Add_pos(c.X1 - 1,c.Y2 + 1,v);Add_pos(c.X1 + 1,c.Y2 + 1,v);
Add_pos(c.X1 - 1,c.Y1,-v);Add_pos(c.X1 + 1,c.Y1,-v);
}
}
else if(c.Y1 == Y) {
if(c.X1 <= X) {
Add_pos(c.X2,c.Y1,v);Add_pos(c.X1 - 1,c.Y1,-v);
Add_pos(c.X1 - 1,c.Y1 - 1,v);Add_pos(c.X1 - 1,c.Y1 + 1,v);
Add_pos(c.X2,c.Y1 - 1,-v);Add_pos(c.X2,c.Y1 + 1,-v);
}
else {
Add_pos(c.X1,c.Y1,v);Add_pos(c.X2 + 1,c.Y1,-v);
Add_pos(c.X1,c.Y1 - 1,-v);Add_pos(c.X1,c.Y1 + 1,-v);
Add_pos(c.X2 + 1,c.Y1 - 1,v);Add_pos(c.X2 + 1,c.Y1 + 1,v);
}
}
else if(c.X1 < X) {
if(c.Y1 < Y) {
Add_pos(c.X2,c.Y2,v);Add_pos(c.X2,c.Y1 - 1,-v);
Add_pos(c.X1 - 1,c.Y2,-v);Add_pos(c.X1 - 1,c.Y1 - 1,v);
}
else {
Add_pos(c.X2,c.Y1,v);Add_pos(c.X1 - 1,c.Y1,-v);
Add_pos(c.X2,c.Y2 + 1,-v);Add_pos(c.X1 - 1,c.Y2 + 1,v);
}
}
else {
if(c.Y1 < Y) {
Add_pos(c.X1,c.Y2,v);Add_pos(c.X1,c.Y1 - 1,-v);
Add_pos(c.X2 + 1,c.Y2,-v);Add_pos(c.X2 + 1,c.Y1 - 1,v);
}
else {
Add_pos(c.X1,c.Y1,v);Add_pos(c.X1,c.Y2 + 1,-v);
Add_pos(c.X2 + 1,c.Y1,-v);Add_pos(c.X2 + 1,c.Y2 + 1,v);
}
}
} void Solve() {
int op,X1,X2,Y1,Y2;
int64 c;
while(T--) {
read(op);read(X1);read(Y1);read(X2);read(Y2);
Matrix t;
if(op == 0) {
int64 res = V;
t = (Matrix){X - X1,X + X2,Y - Y1,Y + Y2};
for(int i = 1 ; i <= tot ; ++i) {
res = gcd(res,Calc(MK[i],t));
}
out(res);enter;
}
else {
t = (Matrix){X1,X2,Y1,Y2}; read(c); if(X1 <= X && X <= X2 && Y1 <= Y && Y <= Y2) {
V += c;
Add_pos(X,Y,c);
Add_pos(X - 1,Y,-c);
Add_pos(X + 1,Y,-c);
Add_pos(X,Y - 1,-c);
Add_pos(X,Y + 1,-c);
Add_pos(X - 1,Y - 1,c);
Add_pos(X - 1,Y + 1,c);
Add_pos(X + 1,Y - 1,c);
Add_pos(X + 1,Y + 1,c);
}
for(int i = 1 ; i <= tot ; ++i) {
Add(MK[i],t,c);
}
}
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}

【LOJ】#2672. 「NOI2012」魔幻棋盘的更多相关文章

  1. @loj - 2674@ 「NOI2012」美食节

    目录 @description@ @solution@ @accepted code@ @details@ @description@ CZ 市为了欢迎全国各地的同学,特地举办了一场盛大的美食节. 作 ...

  2. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  3. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  4. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  5. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  6. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

  7. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

  8. Loj #3056. 「HNOI2019」多边形

    Loj #3056. 「HNOI2019」多边形 小 R 与小 W 在玩游戏. 他们有一个边数为 \(n\) 的凸多边形,其顶点沿逆时针方向标号依次为 \(1,2,3, \ldots , n\).最开 ...

  9. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

随机推荐

  1. SpringBoot中AOP的配置

    AOP目的: 面向切面编程(aspect-oriented programming,AOP)主要实现的目的是针对业务处理过程中的切面进行提取,诸如日志.事务管理和安全这样的系统服务,从而使得业务逻辑各 ...

  2. Python排序算法之直接插入排序

    插入排序的主要思想是每次取一个列表元素与列表中已经排序好的列表段进行比较,然后插入从而得到新的排序好的列表段,最终获得排序好的列表. 比如,待排序列表为[49,38,65,97,76,13,27,49 ...

  3. dubbo Filter

    官方说明: 调用拦截扩展 扩展说明 服务提供方和服务消费方调用过程拦截,Dubbo 本身的大多功能均基于此扩展点实现,每次远程方法执行,该拦截都会被执行,请注意对性能的影响. 约定: 用户自定义 fi ...

  4. nginx.conf 基础配置

    ### 全局块开始### #配置允许运行nginx服务器的用户和用户组 user nobody; #配置允许nginx进程生成的worker process 数 worker_processes 1; ...

  5. VS2010 项目属性的默认包含路径设置方法

    VS2010 项目属性的默认包含路径设置方法 分类: c++小技巧2014-01-10 10:16 1358人阅读 评论(0) 收藏 举报 c++ 有两种方法可以设置vs2010的默认包含路径 方法一 ...

  6. VC++的全局变量(转)

    全局变量一般这样定义:1.在一类的.cpp中定义 int myInt;然后再在要用到的地方的.cpp里extern int myInt:这样就可以用了. 2.在stdafx.cpp中加入:int my ...

  7. transform 动画效果

    http://www.css88.com/tool/css3Preview/Transform.html transform的含义是:改变,使…变形:转换 transform的属性包括:rotate( ...

  8. 对接微信支付使用HMAC-SHA256使用签名算法实现方式

    最近做微信押金支付对接,很多坑,心累!这里提醒一下各位: 首先,确保自己商户号进了白名单,没有需要联系客服,否则接口是调不通的,会一直提示参数错误 其次,确保接口文档是最新的,最好去官网去看,否则可能 ...

  9. 【Linux技术】autotools制作makefile过程详解【转】

    转自:http://www.cnblogs.com/lcw/p/3159461.htmlPreface Makefile固然可以帮助make完成它的使命,但要承认的是,编写Makefile确实不是一件 ...

  10. 双机/RAC/Dataguard的区别【转】

    本文转自 双机/RAC/Dataguard的区别-jasoname-ITPUB博客 http://blog.itpub.net/22741583/viewspace-684261/ Data Guar ...