CF983-Div.2-E

news/2024/11/13 21:04:44/文章来源:https://www.cnblogs.com/superl61/p/18544796

CF983-Div.2-E

自己独立完成的一道蓝题!中间思路有很多想复杂了的地方,但最终还是做出来了!记录一下自己的心路历程。

手玩样例找思路

狂搓4个样例!搓到第4个,把每个位置操作完之后的序列都写下来观察,写的过程中猛然发现数和数之间的操作有一种一环扣一环的感觉,如果按顺序操作,上一个操作完了,到了当前这个,它的操作方式其实是很固定的。

想到解方程。又感觉本题很可以二分,因此想到二分 + 高斯消元的思路。时间复杂度 \(O(n^3logV)\)

怎么快速解方程

不管能不能二分答案,先想固定每个数最终的值 \(x\) 过后,怎么判断这个方程有没有一组解,满足 \(v_{1 \sim n}\) 都是非负整数。

方程组写出来:

我们记 \(a_i = x - c_i\)\(c_i\) 表示原始序列(和原题不同)

\[\begin{cases}v_n + 2v_1 + v_2 & = a_1\\v_1 + 2v_2 + v_3 & = a_2\\v_2 + 2v_3 + v_4 & = a_3\\\vdots\\v_{n - 2} + 2v_{n - 1} + v_n & = a_{n - 1}\\v_{n - 1} + 2v_n + v_{1} & = a_{n}\end{cases} \]

完全满足3个3个轮换对称的形式,刚好 \(n\) 个方程,所以是有唯一解的。

考虑怎么避开高斯消元,比较快速地解出这个方程。

找找轮换对称有没有什么性质。首先全部加起来刚好是 4 倍的 \(\sum_{i = 1}^{n} vi\)。因此可以在 \(O(n)\) 时间内得到了 \(vsum\)

接着想。想了一段时间发现对每个方程单独下手仍然不方便。就开始乱搞了,先是挑了几个方程出来看尽量能不能凑成接近一个 \(v_{1 \sim n}\) 的形式,发现没什么性质。

然后把所有的奇数项方程加了起来,发现得到:

\[2v_1 + v_2 + v_3 + \dots + v_{n - 1} + 2v_n = a_1 + a_3 + a_5 + \dots + a_n \]

进而在 \(O(n)\) 时间内得到了 \(v_1 + v_n\)

依次带进原方程组中,记 \(b_i = a_i - (v_i + v_{i - 1})\),得到:

\[\begin{cases}v_1 + v_2 & = b_1\\v_2 + v_3 & = b_2\\v_3 + v_4 & = b_3\\\vdots\\v_{n - 1} + v_n & = b_{n - 1}\\v_n + v_{1} & = b_{n}\end{cases} \]

再次全部加在一起可以得 \(vsum\),但已经没用了。

再次把所有的奇数项方程加了起来,得到:

\[2v_1 + v_2 + v_3 + \dots + v_{n - 1} + v_n = b_1 + b_3 + \dots + b_n \]

进而在 \(O(n)\) 时间内得到了 \(v_1\),最后就可以依次得到 \(v_1 \sim n\)

梳理思路

结合方程组理解每次操作,发现如果序列已经全部变成一样的数 \(x\) 了,此时每个位置在操作1次,相当于序列全部变成了 \(x + 4\),仍然是一组合法的解。结合题中所说的 “输出任意一个解”,更加肯定这个思路是对的。

于是发现不用二分了,对任意 \(x\)\(x - 2 \sim x + 2\) 中必然有一个值是可以生成一组合法解的。

\(x\) 取极大值就肯定有合法解了,我取的 1e18。

因此在 \(O(\sum n)\) 的时间内就可以解决这个问题。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
#define G(i,r,l) for(int i(r);i>=(l);--i)
using namespace std;
using ll = long long;
using super = __int128;
const int LEN = 5e6;
char buf[100], *p1 = buf, *p2 = buf, obuf[LEN], *o = obuf;
inline int gc(){return (p1 == p2) && (p2 = (p1 = buf) + fread(buf, 1, 100, stdin), p1 == p2) ? EOF : *p1++;
}
inline int rd(){int x = 0; char ch; bool f = 1;while(!isdigit(ch = gc())) f ^= (ch == '-');do x = (x << 3) + (x << 1) + (ch ^ 48); while(isdigit(ch = gc()));return f ? x : -x;
}
inline void output(super x){if(x < 0){x = ~x + 1;*o++='-';}if(x > 9) output(x / 10);*o++=(x % 10 + 48);
}
inline void write(super x, char c){output(x);*o++=c;
}
const int N = 2e5 + 5;
int n, T;
int c[N];
super v[N], a[N], b[N];
const int debug = 10004;
bool suan(ll x){super vsum = 0;b[0] = 0;F(i, 1, n) {a[i] = x - c[i];vsum += a[i];if(i & 1) b[0] += a[i];}if(vsum % 4 != 0) return 0;vsum /= 4;b[0] -= vsum * 2;v[1] = 0;F(i, 1, n){b[i] = a[i] - b[i - 1];	if(i & 1) v[1] += b[i];if(x == debug){cerr << (ll)b[i] << ' ';}}v[1] -= vsum;if(v[1] < 0) return 0;F(i, 2, n) {v[i] = b[i - 1] - v[i - 1];if(v[i] < 0) return 0;}return 1;
}
void Main(){n = rd();int flag = 1;F(i, 1, n) {c[i] = rd();if(i > 1 && c[i] != c[i - 1]) flag = 0;}if(flag){F(i, 1, n) write(0, ' ');return ;}const ll MAXN = 1e18;for(ll r = MAXN - 5; r <= MAXN; ++ r){if(suan(r)){F(i, 1, n) write(v[i], ' ');return ;}}
}
signed main(){
//	freopen("E.in","r",stdin);
//	freopen("E.out","w",stdout);T = rd();while(T --){Main();*o++='\n';}fwrite(obuf, o - obuf, 1, stdout);return fflush(0), 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/833142.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jvm 垃圾回收算法的评价标准

如何实现回收的(核心思想): 1. 找到内存中存活的对象(与GC Root相关联) 2. 释放不再存活对象的内存,使得程序能再次利用这部分空间 --------------------------------------------------------------------------------- 垃圾回收算法的分类: -------- ----------------…

GO面试-切片

一、结构介绍 切片(Slice)在 Go 语言中,有一个很常用的数据结构,切片是一个拥有相同类型元素的可变长度的序列,它是基于数组类型做的一层封装。它非常灵活,支持自动扩容。并发不安全。 切片是一种引用类型,它有三个属性:指针,长度和容量。 底层源码定义: type slice …

系统管理体系——软件包管理

1.Linux系统管理体系——软件包管理Linux下面的软件包格式为:rpm格式(红帽系列系统,CentOS,麒麟系统)或deb格式(Debian,Ubuntu)安装软件方式 举例 说明 应用场景yum/apt 方式 点外卖,缺啥少啥,外卖解 决 通过网络下载软件包,替我们安装, 如果 有依赖自动下载依赖并安装. …

Linux12位权限管理体

1. Linux12位权限管理体 1.1 权限管理概述Linux通过rwx3种权限控制系统与保护系统,组成9位权限. Linux权限体系中还有3位特殊权限,组合起来就是12位权限体系. Linux这简单的rwx控制整个Linux系统的安全,权限与用户共同组成Linux系统的安全防护体系.1.2 Linux权限计算 2.0 rwx权…

Java流程控制(三)

用户交互Scanner(java.util.Scanner获取用户的输入)//基本语法 Scanner s = new Scanner(System.in)通过Scanner类的next()与nextLine()方法获取输入的字符串,使用hasNext()与hasNextLine()判断是否还有输入的数据(Next不能得到带有空格的字符串,NextLine可以获得空白)im…

0.1+0.2=0.30000000000000004

看下效果这个网站能找到你想要的答案 https://0.30000000000000004.com/ 十进制转二进制 十进制整数转换为二进制整数采用"除2取余,逆序排列"法。 具体做法是:用2整除十进制整数,可以得到一个商和余数; 再用2去除商,又会得到一个商和余数,如此进行,直到商为小…

「AT_diverta2019_2_e」Balanced Piles 题解

题意描述 有一个长度为 \(N(2\le N \le 10^6)\) 的数组,一开始所有元素均为 \(0\)。 设 \(M\) 为当前数组中的最大元素,\(m\) 是当前数组中的最小元素,你可以执行若干次以下操作:选择一个大小为 \(m\) 的元素,把他变为 \(x\),其中 \(M\le x \le M+D\) 且 \(m<x\)。 求…

团队项目Scrum冲刺-day3

一、每天举行站立式会议 站立式会议照片一张昨天已完成的工作成员 任务陈国金 用户模块的部分接口凌枫 用户登录页面陈卓恒 用户注册界面谭立业 题目搜索页面部分内容廖俊龙 接口测试曾平凡 前端页面测试曾俊涛 题目模块的部分接口薛秋昊 题目提交模块的部分接口今天计划完成的…

Logisim-016-海明解码

仓库地址 https://gitee.com/gitliang/logisim-to-cpu

Logisim-016-海明编码

仓库地址 https://gitee.com/gitliang/logisim-to-cpu

Object

Object 类是 Java 中的顶级父类, 所有的类都直接或间接继承于 Object 类. Object 类中的方法可以被所有子类访问. Object 类没有成员变量, 所以只有无参构造方法. Java 中, 子类的共性才会往父类中去抽取, 然而不可能有一个属性是所有类的共性, 所以在 Object 这个类中, 是没有…

Windows平台下安装与配置MySQL5.7

1.下载mysql安装文件 下载地址:https://downloads.mysql.com/archives/installer/2.安装与配置MySQL 双击打开,接受许可协议,点击下一步:选择自定义安装,点击下一步:选择要安装的产品,点击下一步:点击执行按钮:安装完成,点击下一步进入配置界面:配置界面继续点击下一…