题解-Decrease
[MdOI2020] Decrease
古老的博文。
今天巨佬团队 \(\texttt{luogu}\) 公开赛中的第三题,当时我写了好久才想到暴力做法 \(\texttt{42分}\),后来我还很离谱的写了个二维线段树,最终也没做出来。看来我还是太蒻了。
其实此题的做法是:简单差分
审题很重要,按照题目描述输入矩阵,题目中也说了,要快读:
for(int i=1,x,y,z;i<=m;i++){
x=d(),y=d(),z=d();
a[x][y]=z;
}
暴力做法:枚举覆盖正方形的左上角,暴力覆盖。 代码:
int main(){
n=d(),m=d(),k=d();
for(int i=1,x,y,z;i<=m;i++){
x=d(),y=d(),z=d();
a[x][y]=z;
}
for(int i=1;i<=n-k+1;i++)
for(int j=1;j<=n-k+1;j++)
if(a[i][j]!=0){
ans+=abs(a[i][j]);
int tmp=a[i][j];
for(int x=i;x<=i+k-1;x++)
for(int y=j;y<=j+k-1;y++)
a[x][y]-=tmp;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(a[i][j]!=0) return puts("-1"),0;
printf("%lld\n",ans);
return 0;
}
这么蒟蒻的做法,我拿到了 \(\texttt{42分}\),可见暴力的重要性。
然后我们发现,修改的区间一定是一个矩形,而且是增减修改,并且是统一修改,就应该想到用差分。把每行单独拎出来差分一下,形成差分数组 \(cf[][]\):
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cf[i][j]=a[i][j]-a[i][j-1];
然后暴力枚举覆盖正方形左上角端点,如果不为零就把整个右下角的 \(k\times k\) 矩阵减去左上角端点的数,然后让 \(\texttt{ans}\) 加上左上角端点数的绝对值。因为当枚举到一个端点的时候,它同一行左端的端点肯定被清零了,所以到这个端点时这个端点的值就是 \(cf[][]\) 了。代码:
for(int i=1;i<=n-k+1;i++)
for(int j=1,num=0;j<=n-k+1;j++){
num=cf[i][j];
if(num!=0){
ans+=abs(num);
for(int t=i;t<=i+k-1;t++)
cf[t][j]-=num,cf[t][j+k]+=num; //k*k矩阵修改通过差分优化,时间复杂度为O(n)
}
}
因为要覆盖的左端点少,所以这样的代码时间复杂度是合理的。
题目中说还有“无法使矩阵中所有数都变为 \(0\)”的情况,所以最后再 \(n\times n\) 暴力扫一遍差分矩阵,如果还有没清零的数,就 \(\texttt{puts("-1")}\)。代码:
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(cf[i][j]) return puts("-1"),0;
就这么简单,普及难度,可是我比赛时缺没想到。如果你懂了,那么蒟蒻就放代码了:
#include <bits/stdc++.h>
using namespace std;
#define lng long long
namespace rd{
const int L=1<<16;
char buf[L],*S,*T;
inline char Gc_(){
if(S==T){T=(S=buf)+fread(buf,1,L,stdin);
if(S==T) return EOF;}
return *S++;
}
inline char Gc(){return getchar();}
inline int d(){
char c;int f=1,x;
for(c=Gc();c>'9'||c<'0';c=Gc())
if(c=='-') f=-1;
for(x=0;c>='0'&&c<='9';c=Gc())
x=(x<<1)+(x<<3)+c-'0';
return x*f;
}
}using namespace rd;
const int N=5e3+10;
int n,m,k,a[N][N];
lng ans;
int cf[N][N];
int main(){
n=d(),m=d(),k=d();
for(int i=1,x,y,z;i<=m;i++){
x=d(),y=d(),z=d();
a[x][y]=z;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cf[i][j]=a[i][j]-a[i][j-1];
for(int i=1;i<=n-k+1;i++)
for(int j=1,num=0;j<=n-k+1;j++){
num=cf[i][j];
if(num!=0){
ans+=abs(num);
for(int t=i;t<=i+k-1;t++)
cf[t][j]-=num,cf[t][j+k]+=num;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(cf[i][j]) return puts("-1"),0;
printf("%lld\n",ans);
return 0;
}
祝大家学习愉快!
题解-Decrease的更多相关文章
- 题解 【[MdOI2020] Decrease】
\[ \texttt{Preface} \] 感觉 C 比 B 还简单? \[ \texttt{Description} \] 给定一个 \(n×n\) 的矩阵,你可以进行若干次操作. 每次操作,你可 ...
- CF1012C Hills 题解【DP】
思路还是比较简单的 dp 吧,但是就是想不出来-甚至类似的方程都被自己推翻了 Description Welcome to Innopolis city. Throughout the whole y ...
- Atcoder arc079 D Decrease (Contestant ver.) (逆推)
D - Decrease (Contestant ver.) Time limit : 2sec / Memory limit : 256MB Score : 600 points Problem S ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
随机推荐
- 二、多线程及服务器编程总结------linux多线程服务端编程
- selenium之 定位以及切换frame(iframe)(转)
frame标签有frameset.frame.iframe三种,frameset跟其他普通标签没有区别,不会影响到正常的定位,而frame与iframe对selenium定位而言是一样的,seleni ...
- linux服务器间配置ssh免密连接
先说一下,我用的centos7,root用户.ssh的原理就不说了,网上介绍的文章很多,直接开始说操作步骤吧: 1.首先确认有没有安装ssh,输入 rpm -qa |grep ssh查看 这样就表示安 ...
- 重构克隆rbd的数据
前言 之前写过一篇重构rbd的元数据的文章,讲的是如果rbd的元数据丢失了,数据还在的时候怎么恢复相关的元数据,但是实际使用的场景是,集群可能崩溃了,数据还在,osd无法拉起来,数据又很重要,需要把数 ...
- 重写ceph-lazy
前言 这个工具最开始是从sebastien的blog里面看到的,这个是 Gregory Charot(工具的作者)写的,通常我们在获取一个ceph的信息的时候,需要敲一连串的命令去获得自己需要的信息, ...
- 贼厉害,手撸的 SpringBoot 缓存系统,性能杠杠的!
一.通用缓存接口 二.本地缓存 三.分布式缓存 四.缓存"及时"过期问题 五.二级缓存 缓存是最直接有效提升系统性能的手段之一.个人认为用好用对缓存是优秀程序员的必备基本素质. 本 ...
- sqlilab less28 less28a
less-28 less-28a 二者相差不大 单引号小括号包裹,黑名单过滤--,#,空格,union空格select(不区分大小写) less-28的黑名单 less-28a的黑名单 %a0,不被 ...
- 吉他指弹入门——贝斯(walking bass)
在每一个乐队中都有一个神秘而低调的乐手,在现场演奏中你甚至感觉不到他的存在,但是他又异常重要.即是鼓手打拍的好伙伴,又是吉他手忘乎所以solo时的警报器.没错,这个人就是贝斯手.要是我们做了什么气跑了 ...
- css3系列之transform 详解scale
scale() scaleX() scaleY() scaleZ() scale3d() 改变的不是元素的宽高,而是 X 和 Y 轴的刻度 本章有个很冷门的知识点 → scale 和 rotate 一 ...
- LeetCode周赛#203 题解
1561. 你可以获得的最大硬币数目 #贪心 题目链接 题意 有 3n 堆数目不一的硬币,你和你的朋友们打算按以下方式分硬币: 每一轮中,你将会选出 任意 3 堆硬币(不一定连续). Alice 将会 ...