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;
}