Easy Construction

Easy Construction 传送门

E. Easy Construction

Problem Description

Roundgod is given n,k, construct a permutation P of 1∼n satisfying that for all integers i in [1,n] , there exists a contiguous subarray in P of length i whose sum is k modulo n. If there are multiple solutions, print any of them. If there is no solution, print “-1” in one line.

Input

2 1

Output

1 2

Note

The sum of subintervals [1],[1,2] both satisfy ≡ 1(mod2), and their lengths are 1,2 respectively.

Input

3 1

Output

-1


题目大意

给定 n,k,问是否可以构造一个 1~n 的排列P,使得对于 1~n 中任意的数 i,P 都存在一个 长为 i 的连续子区间,使得区间和模 n 余 k。有解输出任意一组,无解输出 -1


解题思路

当 i = n 时,连续子区间是它本身,区间和为Sn,所以当有解的时候,Sn mod n = k
因此 (( n*n+n )/ 2 ) mod n = k 成立是有解无解的分界线
如果有解,那我们就分类构造子序列 ( n为偶数 ,n为奇数 )
当n为偶数,可以推出 k=n / 2,我们先把n 和 k 直接构造出来,然后后面的用交叉构造的方式构造
即子序列可以交叉构造为 {n, n/2, 1, n-1, 2, n-2, …}
当n为奇数,可以推出 k = 0,我们就先把n构造出来,然后后面用交叉构造的方式构造即可,又由于此时 k = 0
所以我们的子序列可以交叉构造为 {n, 1, n-1, 2, n-2, …}
Ps:赛中有点迷,赛后看了出题人的讲解后才理解清楚透彻

AC代码

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
	int n , k;
	cin>>n>>k;
	int ret = ((n*n+n)/2)%n;//P of length i whose sum is k modulo n --> Sn % n = k
	if(ret != k)
	{	
		cout<<"-1";
	}else
	{
		if(n % 2 == 0)
		{
			//如果n是偶数,可知k=n/2,则 {n, n/2, 1, n-1, 2, n-2, ...} 	
			cout<<n<<" "<<n/2<<" ";
			for(int i = 1 ; i < n/2 ; i++)//交叉构造
			{
				cout<<i<<" "<<n-i<<" ";
			}
			
		}else
		{
			//如果n是奇数,可知k=0,则 {n, 1, n-1, 2, n-2, ...} 
			cout<<n<<" ";
			for(int i = 1 ; i <= n/2 ; i++)//交叉构造
			{
				cout<<i<<" "<<n-i<<" ";
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_46425926/article/details/107625916