[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的更多相关文章

  1. 题解 【[MdOI2020] Decrease】

    \[ \texttt{Preface} \] 感觉 C 比 B 还简单? \[ \texttt{Description} \] 给定一个 \(n×n\) 的矩阵,你可以进行若干次操作. 每次操作,你可 ...

  2. CF1012C Hills 题解【DP】

    思路还是比较简单的 dp 吧,但是就是想不出来-甚至类似的方程都被自己推翻了 Description Welcome to Innopolis city. Throughout the whole y ...

  3. Atcoder arc079 D Decrease (Contestant ver.) (逆推)

    D - Decrease (Contestant ver.) Time limit : 2sec / Memory limit : 256MB Score : 600 points Problem S ...

  4. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  5. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  6. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  7. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  8. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  9. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

随机推荐

  1. tcp/udp注意事项

  2. C++的四种强制转型形式:

    C++同时提供了四种新的强制转型形式(通常称为新风格的或C++风格的强制转型): const_cast(expression)dynamic_cast(expression)reinterpret_c ...

  3. 基于FFmpeg的Dxva2硬解码及Direct3D显示(一)

    目录 前言 名词解释 代码实现逻辑 前言 关于视频软解码的资料网上比较多了,但是关于硬解可供参考的资料非常之有限,虽然总得来说软解和硬解的基本逻辑一样,但是实现细节上的差别还是比较多的.虽然目前功能已 ...

  4. Mon失效处理方法

    假设环境为三个mon,主机名为mon1.mon2.mon3,现在mon3上面的系统盘损坏,mon的数据完全丢失,现在需要对mon3进行恢复处理 1.停止所有mon进程,可以不停其他进程,需要停止内核客 ...

  5. 探究:nuget工具对不再使用的dll文件的处理策略

    背景介绍 nuget是.net平台有效的包管理工具,相信每个C#开发者对它都不陌生. 本文我们来探究一下nuget对不再使用的dll文件的处理策略,分为如下2个场景: 场景A:包A1.0原来包含New ...

  6. 深度分析:面试阿里,字节99%会被问到Java类加载机制和类加载器

    1. 类加载机制 所谓类加载机制就是JVM虚拟机把Class文件加载到内存,并对数据进行校验,转换解析和初始化,形成虚拟机可以直接使用的Jav类型,即Java.lang.Class. 2. 类加载的过 ...

  7. Mac虚拟环境安装django

    安装:pip3 install virtualenv 创建:Virtualenv env01 激活:Source env01/bin/activate django安装:pip3 install dj ...

  8. synchronized关键字的可重入性

    /**父类*/public class SynchronizedDemo1 implements Runnable { @Override public void run() { try { meth ...

  9. 执行文件异常报错:ImportError: attempted relative import with no known parent package

    这个问题困扰了我很久了,网上的解决方法都很一致,找来找去都是一样的解决方法,在导入包的文件和执行文件加入 1 print('__file__={0:<35} | __name__={1:< ...

  10. 【linux】串口通讯工具-minicom简介+简单操作

    目录 前言 简介 尝试运行 配置 minicom 运行 minicom minicom 其它操作 前言 windows 上有不少的串口通信工具了,今天介绍一个linux下的一个串口通信工具-minic ...