题目大意
给定
n
,
有
T
组数据,满足
题目分析
大家喜闻乐见的数论构造题。
如果单纯地模拟题意,是想不到什么好的解法的。因为这样没用充分利用题目给的
E
和
既然是对连续子序列和的限制,很容易想到用前缀和来差分一下。设
EvenPrefixsum
表示偶数前缀和个数,
OddPrefixsum
表示奇数前缀和个数。
首先显然有
EvenPrefixsum+OddPrefixsum=n+1
注意前缀和包括位置 0 。
然后显然奇数前缀和与偶数前缀和差分才能得到奇数连续子序列,那么就有
那么我们枚举其中一个,就可以利用条件 1 得到另一个,然后用条件
显然直接在位置 EvenPrefixsum 填上唯一一个奇数,其余位置填上偶数即可。至此问题完美解决。
时间复杂度 O(∑n) 。
代码实现
第一次在CC上交题,Submit按钮找了半天。
#include <iostream>
#include <cstdio>
#include <cctype>
using namespace std;
typedef long long LL;
int read()
{
int x=0,f=1;
char ch=getchar();
while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar();
while (isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int N=1000050;
int T,n,E,O;
LL e,o;
int main()
{
freopen("alost.in","r",stdin),freopen("alost.out","w",stdout);
T=read();
while (T--)
{
n=read();
scanf("%lld %lld",&e,&o);
for (E=1;E<=n+1;E++)
{
O=n+1-E;
if (1ll*E*O==o) break;
}
if (1ll*E*O!=o)
{
printf("-1\n");
continue;
}
for (int i=1;i<E;i++) printf("2 ");
if (E<=n) printf("3 ");
for (int i=E+1;i<=n;i++) printf("2 ");
printf("\n");
}
fclose(stdin),fclose(stdout);
return 0;
}