Solution to Luogu P6340

[Problem Discription]\color{blue}{\texttt{[Problem Discription]}}[Problem Discription]

[Analysis]\color{blue}{\texttt{[Analysis]}}[Analysis]

题目相当于给出以下 nnn 个方程:

{an+a1+a2=b1a1+a2+a3=b2a2+a3+a4=b3⋯an−1+an+a1=bn\begin{cases} &a_{n} &+ &a_{1} &+ &a_{2} &= &b_{1}\\ &a_{1} &+ &a_{2} &+ &a_{3} &= &b_{2}\\ &a_{2} &+ &a_{3} &+ &a_{4} &= &b_{3}\\ &\cdots\\ &a_{n-1} &+ &a_{n} &+ &a_{1} &= &b_{n} \end{cases}⎩ ⎨ ⎧ana1a2⋯an−1++++a1a2a3an++++a2a3a4a1====b1b2b3bn

把所有方程相加,我们可以得到最终构造的数组一定满足条件 111: ∑i=1nai=13∑i=1nbi\sum\limits_{i=1}^{n} a_{i}=\dfrac{1}{3} \sum\limits_{i=1}^{n}b_{i}i=1∑nai=31i=1∑nbi。记该数为 tar\text{tar}tar。

同时,通过方程之间相互消元可以得到

ai+3=ai+bi+2−bi+1(∗)a_{i+3}=a_{i}+b_{i+2}-b_{i+1}\quad (*)ai+3=ai+bi+2−bi+1(∗)

即若 aia_{i}ai 已知,则 ai+3,ai+6,⋯a_{i+3},a_{i+6},\cdotsai+3,ai+6,⋯ 均已知。

如果 nmod  3≠0n \mod 3 \not= 0nmod3=0,那么只需要给定 A1A_{1}A1,就可以通过 (∗)(*)(∗) 式算出所有的 A2⋯nA_{2 \cdots n}A2⋯n。但是这个数列不一定满足条件 111。没关系,我们记 sum=∑i=1nAi\text{sum}=\sum\limits_{i=1}^{n} A_{i}sum=i=1∑nAi,则 AiA_{i}Ai 相对 aia_{i}ai 的进动量为 −tar−sumn-\dfrac{\text{tar}-\text{sum}}{n}−ntar−sum,修正后即可得到正确答案。

如果 nmod  3=0n \mod 3 = 0nmod3=0,则需要给定 A1,2,3A_{1,2,3}A1,2,3 才能确定整个数列。注意,这三个数不能随便给,因为后面修正的时候每个数都减去相同的数,因此每三个数的和一定增大 333 的倍数(包括负倍数),所以必须保证初始的 A1+A2+A3 mod a1+a2+a3≡3A_{1}+A_{2}+A_{3} \bmod a_{1}+a_{2}+a_{3} \equiv 3A1+A2+A3moda1+a2+a3≡3。

Code\color{blue}{\text{Code}}Code

cpp 复制代码
```const int N=1e4+100;
typedef long long ll;

int b[N],a[N],n;
bool vis[N];
ll sum,tar,reg;

int add(int a,int b){
	if (a+b>n) return a+b-n;
	else return a+b;
}

void manifest(int pos,int val){
	int cur=pos,lst=add(cur,3);
	
	a[pos]=val;
	vis[pos]=true;
	
	while (!vis[lst]){
		vis[lst]=true;
		a[lst]=a[cur]+b[add(cur,2)]-b[add(cur,1)];
		
		cur=lst;
		lst=add(cur,3); 
	}
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&b[i]);
		tar+=b[i];
	}
	
	if (tar%3){
		printf("No Solution");
		return 0;
	}
	
	tar/=3;
	
	if (n%3) manifest(1,46);
	else{
		manifest(1,18);
		manifest(2,26);
		manifest(3,b[2]-44);
	}
	
	for(int i=1;i<=n;i++)
		sum+=a[i];
	
	reg=(tar-sum)/n;
	
	for(int i=1;i<=n;i++)
		a[i]+=reg; 
	
	for(int i=1;i<=n;i++)
		printf("%d ",a[i]);
	
	return 0;
}
相关推荐
干前端6 分钟前
Message组件和Vue3 进阶:手动挂载组件与 Diff 算法深度解析
javascript·vue.js·算法
ゞ 正在缓冲99%…8 分钟前
2025.12.17华为软开
java·算法
子午14 分钟前
【2026原创】文本情感识别系统~Python+深度学习+textCNN算法+舆情文本+模型训练
python·深度学习·算法
Flash.kkl14 分钟前
递归、搜索与回溯算法概要
数据结构·算法
s090713614 分钟前
【MATLAB】多子阵合成孔径声纳(SAS)成像仿真——基于时域反向投影(BP)算法
算法·matlab·bp算法·合成孔径
Xの哲學15 分钟前
Linux Workqueue 深度剖析: 从设计哲学到实战应用
linux·服务器·网络·算法·边缘计算
sin_hielo21 分钟前
leetcode 3047
数据结构·算法·leetcode
JAI科研22 分钟前
MICCAI 2025 IUGC 图像超声关键点检测及超声参数测量挑战赛
人工智能·深度学习·算法·计算机视觉·自然语言处理·视觉检测·transformer
mit6.82424 分钟前
思维|状压dp
算法
天赐学c语言24 分钟前
1.17 - 排序链表 && 虚函数指针是什么时候初始化的
数据结构·c++·算法·链表·leecode