[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. 二、多线程及服务器编程总结------linux多线程服务端编程

  2. selenium之 定位以及切换frame(iframe)(转)

    frame标签有frameset.frame.iframe三种,frameset跟其他普通标签没有区别,不会影响到正常的定位,而frame与iframe对selenium定位而言是一样的,seleni ...

  3. linux服务器间配置ssh免密连接

    先说一下,我用的centos7,root用户.ssh的原理就不说了,网上介绍的文章很多,直接开始说操作步骤吧: 1.首先确认有没有安装ssh,输入 rpm -qa |grep ssh查看 这样就表示安 ...

  4. 重构克隆rbd的数据

    前言 之前写过一篇重构rbd的元数据的文章,讲的是如果rbd的元数据丢失了,数据还在的时候怎么恢复相关的元数据,但是实际使用的场景是,集群可能崩溃了,数据还在,osd无法拉起来,数据又很重要,需要把数 ...

  5. 重写ceph-lazy

    前言 这个工具最开始是从sebastien的blog里面看到的,这个是 Gregory Charot(工具的作者)写的,通常我们在获取一个ceph的信息的时候,需要敲一连串的命令去获得自己需要的信息, ...

  6. 贼厉害,手撸的 SpringBoot 缓存系统,性能杠杠的!

    一.通用缓存接口 二.本地缓存 三.分布式缓存 四.缓存"及时"过期问题 五.二级缓存 缓存是最直接有效提升系统性能的手段之一.个人认为用好用对缓存是优秀程序员的必备基本素质. 本 ...

  7. sqlilab less28 less28a

    less-28  less-28a 二者相差不大 单引号小括号包裹,黑名单过滤--,#,空格,union空格select(不区分大小写) less-28的黑名单 less-28a的黑名单 %a0,不被 ...

  8. 吉他指弹入门——贝斯(walking bass)

    在每一个乐队中都有一个神秘而低调的乐手,在现场演奏中你甚至感觉不到他的存在,但是他又异常重要.即是鼓手打拍的好伙伴,又是吉他手忘乎所以solo时的警报器.没错,这个人就是贝斯手.要是我们做了什么气跑了 ...

  9. css3系列之transform 详解scale

    scale() scaleX() scaleY() scaleZ() scale3d() 改变的不是元素的宽高,而是 X 和 Y 轴的刻度 本章有个很冷门的知识点 → scale 和 rotate 一 ...

  10. LeetCode周赛#203 题解

    1561. 你可以获得的最大硬币数目 #贪心 题目链接 题意 有 3n 堆数目不一的硬币,你和你的朋友们打算按以下方式分硬币: 每一轮中,你将会选出 任意 3 堆硬币(不一定连续). Alice 将会 ...