无知时诋毁原神——题解

P8880 无知时诋毁原神

题意简述:

给定一个0n1 的排列 c。构造两个同样为 0n1 的排列的 ab,满足 i[1n]ci=(ai+bi)modn。如果不存在,请输出 1

题解

构造题考脑子……

n 在数据范围下等价于是让我们求出两个序列 ab 使得 ai+bi=ci+nci。由于每一个 i 相互独立,所以实际上我们不需要管 c 的顺序,我们只考虑拼出这 n 个数即可。
首先直觉告诉我们,方案数应该是有不少的,但应该有一种固定的构造方案。并且拼出大于等于 n 的数与小于 n 的数的个数应该是比较均衡的。我们来先玩玩小数据看看规律。

n=3

a:0,2,1。

b:0,2,1。

n=5

a:0,3,1,4,2。

b:0,3,1,4,2。

n=7

a:0,4,1,5,2,6,3。

b:0,4,1,5,2,6,3。

n=246。无解

我们发现,在 357 三种情况,我们都可以构造出一组 ab 完全一样的数据。下面我们来证明当 n 为奇数的时候存在这样一种构造方案。

首先证明充分性:ab 完全一样,意味着拼出来的数都是偶数,那么小于 n 的偶数只有 n2 个,并取 024n1

这里就用去了 0n2,考虑剩下的数 n2n1

将这些数全部减去 n2(注意这里带个小数)就得到了两数之和最终减去 n 的结果。此时剩下的数就取 0.51.52.53.5n22,这些数加上就得到了所有的奇数 1357,故在 n 为奇数的时候这个方案是优秀的。

然后再来思考一下偶数的情况,为什么我们试三个偶数都是无解呢?

由于刚刚的奇数情况,我们用到了奇偶性的思想,考虑再从奇偶性的角度考虑证明偶数无解或者一种优秀的构造方案。

由于是偶数,ai+bimodn 的奇偶性是不变的。那么奇数就只能由一奇一偶来拼出来。由于构造前后奇数个数不变,所以我们就用去了 a 中所有的奇数与 b 中所有的偶数,剩下的数也只能奇偶拼出奇数,故这是错误的,偶数情况无解。

故就得到了本题代码:

int n,a[5000005],b[5000050],vis[5000500];
int main(){
	cin>>n;
	for(int i=0;i<n;i++)b[(i<<1)%n]=i;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		a[i]=b[a[i]];
	} 
	for(int i=1;i<=n;i++){
		if(vis[a[i]]){
			puts("-1");
			return 0;
		}
		vis[a[i]]=1;
	}
	for(int i=1;i<=n;i++)cout<<a[i]<<" ";
	puts("");
	for(int i=1;i<=n;i++)cout<<a[i]<<" ";
	return 0;
}
posted @   spdarkle  阅读(122)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示