题解-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 ...
随机推荐
- leetcode 30day--1
Single Number Given a non-empty array of integers, every element appears twice except for one. Find ...
- binary hacks读数笔记(ld 链接讲解 一)
首先我们先看两段代码: a.c extern int shared; int main(){ int a=100; swap(&a,&shared); } b.c int shared ...
- Android studio设置参数文档提示
方法/步骤 进行点击Android studio菜单中的file的选项菜单. 弹出了下拉菜单中进行选择为"settings"的选项的菜单即可. 进入到了settin ...
- Kubernetes笔记(六):了解控制器 —— Deployment
Pod(容器组)是 Kubernetes 中最小的调度单元,可以通过 yaml 定义文件直接创建一个 Pod.但 Pod 本身并不具备自我恢复(self-healing)功能.如果一个 Pod 所在的 ...
- mysql mybatis Date java时间和写入数据库时间不符差一秒问题
1,java的数据库实体定义 private Timestamp createTime:2,非常重要!ddl语句建表字段的单位 datetime要手动设置保留3位毫秒数,不然就四舍五入了! ALTER ...
- diamond收集插件的自定义
diamond是与graphite配合使用的一个数据收集的软件,关于这个配置的资料很多,使用起来也比较简单,详细的安装和配置会在后面的关于整套监控系统的文章里面写到,本篇是专门讲解怎么自定义这个数据收 ...
- 控制算法PID-理解分析1
以下内容是来自网络上的,本人觉得有道理,拷贝下来,由于没有找到最源头的出处,没有注明来自何方. 转载,下面说法应该更通俗易懂一家庭,每次需要开支的时候丈夫P都要拿卡去取钱.需要多少取多少,因为银行最低 ...
- 你真的能分清putc()函数和fputc()函数吗?
最近小编在讲关于C语言文件部分内容,讲到了fputc()函数.前面在讲字符串的时候,我们还学习过putc()函数,我们知道,putc()函数一般用于标准输出,fputc()函数一般用于文件读写.刚才呢 ...
- h5 图片上传旋转问题
https://blog.csdn.net/netdxy/article/details/51518494 https://www.cnblogs.com/liu-fei-fei/p/5974403. ...
- Hadoop window提交出错:Permission denied
错误信息: Caused by: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.AccessControlExcep ...