CF1141C题解

我的思路

这题的一个算式 qi=pi+1piq_{i}=p_{i+1}-p_{i} 让我想到了差分,但是再一看,没有第一项,没办法倒推。

但是,想到 pi=j=1iqjp_i=\displaystyle\sum_{j=1}^iq_j,但没有第一项,那我们先把第一项的值空出来,再求出 pp 数组。

接着,把 pp 数组的值加起来得到 kk,由于 pp 数组是一个排列,所以和一定是 n×(n+1)÷2n\times (n+1)\div 2,然后判断 n×(n+1)÷2modkn\times (n+1)\div 2\bmod k 是否 =0=0,如果否,输出 -1

如果是,那么把 pip_i 加上 n×(n+1)÷2n\times (n+1)\div 2O(n)O(n) 遍历一遍是不是一个排列(我在这里调了好久),如果不是,输出 -1,否则,输出这个 pp 数组。

代码

#include<bits/stdc++.h>
namespace Cmath{
	long long fpow(long long a,long long b,const int k){
		long long sum=1,A=a;
		while(b){
			if(b&1)
				sum=sum*A%k;
			A=A*A%k;
			b>>=1;
		}
		return sum;
	}
	void cmax(long long &a,long long b){
		a=std::max(a,b);
	}
	void cmin(long long &a,long long b){
		a=std::min(a,b);
	}
}
namespace _fast{
	bool print(long long _a,bool _f){
		if(_a<0){
			putchar('-');
			print(-_a,_f|1);
			if(!_f) putchar('\n');
			return 1;
		}
		if(_a<10){
			putchar(_a+'0');
			if(!_f) putchar('\n');
			return 1;
		}
		print(_a/10,_f|1);
		putchar(_a%10+'0');
		if(!_f) putchar('\n');
		return 1;
	}
	void wrap(){
		putchar('\n');
	}
	void _space(){
		putchar(' ');
	}
}
using namespace std;
using namespace Cmath;
using namespace _fast;
int n,p;
long long sum[200010],k,q[200010];
map<int,bool>m;
int main(){
	scanf("%d",&n);
	for(int i=1;i<n;i++){
		scanf("%d",&p);
		sum[i]=sum[i-1]+p;
		k+=sum[i];
	}
	if((1ll*n*(n+1)/2-k)%n!=0) return !print(-1,0);
	k=(1ll*n*(n+1)/2-k)/n;
	for(int i=0;i<n;i++){
		q[i]=sum[i]+k;
		if(q[i]<1||q[i]>n||m[q[i]]) return !print(-1,0);
		m[q[i]]=1;
	}
	for(int i=0;i<n;i++) print(q[i],1),_space();
	return 0;
}
posted @ 2022-12-24 19:18  fengxiaoyi  阅读(28)  评论(0)    收藏  举报  来源