题解

代码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. tomcat修改java不重启

    修改tomcat   server.xml 找到项目的Context配置 <Context docBase="项目名" path="/项目路径" relo ...

  2. Nginx跳转Tomcat

    conf配置: server {         listen       80;         server_name www.-------.com;         server_name_i ...

  3. poj 1961 Period

    Period http://poj.org/problem?id=1961 Time Limit: 3000MS   Memory Limit: 30000K       Description Fo ...

  4. 11 Facts about Data Science that you must know

    11 Facts about Data Science that you must know Statistics, Machine Learning, Data Science, or Analyt ...

  5. 监控Elasticsearch的插件【check_es_system】

    监控Elasticsearch的插件推荐  强大的shell脚本 #!/bin/bash ####################################################### ...

  6. 为什么C++空类的实例大小为1

    [为什么C++空类的实例大小为1] 每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址.所以大小为1. 参考 ...

  7. 谈谈动态地加载Jquery库文件的方法

    有时候,我们可能不会在网页中<script src="jquery.min.js" 来加载 Jquery 库,可能在用户点击某个按钮后,才去加载 Jquery 库. 好处不用 ...

  8. 如何定制Gtk版Emacs的Widget外观

    当我们使用 xlib 版的Emacs时,可以通过 XResource 定义 Emacs 的菜单 栏.工具条.滚动条的外观. 现在,在Linux上我们大多使用 gtk版的Emacs,是否还有办法定义 E ...

  9. 训练赛第一场D题

    解题报告:一开始不知道ATA的意思,后来才知道原来是转置矩阵乘以原来的矩阵.这题说起来比较麻烦就不说了,直接上代码: #include<cstdio> #include<cstrin ...

  10. Linux基础-host文件解析

    任务目标:为集群内的机器设定主机名,利用/etc/hosts文件来解析自己的集群中所有的主机名, 相应的集群的配置应该改成使用主机名的方式 使用 hostnamectl set-hostname 设定 ...