当
k
≤
m
k\le m
k≤m 时,可以先输出
n
−
1
n-1
n−1 个
0
0
0,然后输出
1
1
1 个
k
k
k。
当
k
>
m
k>m
k>m 时,尝试把
k
k
k 分解为多个
2
2
2 的某次幂的异或和。如,若
k
k
k 为
14
14
14,则其二进制表达是
(
1110
)
2
(1110)_2
(1110)2,可以分解为
(
1000
)
2
xor
(
100
)
2
xor
(
10
)
2
(1000)_2\operatorname {xor}\ (100)_2\operatorname {xor}\ (10)_2
(1000)2xor(100)2xor(10)2。易得,某个方案是否合理取决于
max
{
a
i
}
\max\{a_i\}
max{ai},显然如此分解最容易合理。若这种方式分解得到的最大项仍大于
m
m
m,则说明不存在合理的方案。
记分解完后得到的项数为
p
p
p。若
p
≤
n
p\le n
p≤n,则在输出这些项后,需要再输出
n
−
p
n-p
n−p 个
0
0
0;若
p
>
n
p>n
p>n,则根据贪心,需要把前
p
−
n
+
1
p-n+1
p−n+1 项合并得到
s
u
m
sum
sum,如果
s
u
m
>
m
sum>m
sum>m 则输出
−
1
-1
−1,否则输出
s
u
m
sum
sum 后再输出分解后得到的其他项。
最坏时间复杂度为
O
(
T
n
)
\mathcal O(Tn)
O(Tn)。
代码
#include<bits/stdc++.h>usingnamespace std;int t, n, m, k;constint maxn =2e5+100;voidread(int&x){int w =1; x =0;char ch =getchar();while(ch <'0'|| ch >'9'){if(ch =='-') w =-1;
ch =getchar();}while(ch >='0'&& ch <='9'){
x =(x <<1)+(x <<3)+ ch -48;
ch =getchar();}
x *= w;}intmain(){read(t);while(t --){read(n),read(k),read(m);int p =0, a[maxn];if(k <= m){for(int i =1; i < n; i++)printf("0 ");printf("%d\n", k);}else{int flag =0;while(k !=0){if((k &-k)> m){
flag =1;break;}
a[++ p]=(k &-k);
k ^=(k &-k);}if(flag){printf("-1\n");continue;}if(p <= n){for(int i =1; i <= p; i++)printf("%d ", a[i]);for(int i =1; i <= n - p; i++)printf("0 ");printf("\n");}else{int pi =1, sum =0, cur = p;while(cur > n -1){
sum += a[pi ++], cur --;if(sum > m){
flag =1;break;}}if(flag){printf("-1\n");break;}printf("%d ", sum);for(int i = pi; i <= p; i++)printf("%d ", a[i]);printf("\n");}}}return0;}
以
Mex
(
S
)
\operatorname{Mex}(S)
Mex(S) 作为讨论依据。
当
Mex
(
S
)
=
0
\operatorname{Mex}(S)=0
Mex(S)=0 时,由
∏
x
∈
S
x
=
min
x
∈
S
{
x
}
\prod\limits_{x\in S}x=\min\limits_{x\in S}\{x\}
x∈S∏x=x∈Smin{x} 知,
S
S
S 中元素的值只能为
1
1
1;有根据最后一条说明
S
S
S 只能为
{
1
,
1
}
\{1,1\}
{1,1},当且仅当
k
=
2
k=2
k=2 时存在这种方案。
当
Mex
(
S
)
=
1
\operatorname{Mex}(S)=1
Mex(S)=1 时,由最后一条知,
∑
x
∈
S
x
−
max
x
∈
S
x
=
1
\sum\limits_{x\in S} x-\max\limits_{x\in S}{x}=1
x∈S∑x−x∈Smaxx=1,显然除最大值外其他值的和要不为
0
0
0,要不大于
1
1
1,故无解。
当
Mex
(
S
)
=
2
\operatorname{Mex}(S)=2
Mex(S)=2 时,
0
,
1
∈
S
0,1\in S
0,1∈S,若
1
1
1 为
S
S
S 中的最大值,则
S
S
S 为
{
0
,
1
,
1
,
1
}
\{0,1,1,1\}
{0,1,1,1};否则,
S
S
S 为
{
0
,
1
,
1
,
x
}
,
x
>
2
\{0,1,1,x\},x>2
{0,1,1,x},x>2。
当
Mex
(
S
)
=
3
\operatorname{Mex}(S)=3
Mex(S)=3 时,
0
,
1
,
2
∈
S
0,1,2\in S
0,1,2∈S,若
2
2
2 为
S
S
S 中的最大值,则
S
=
{
0
,
1
,
1
,
1
,
2
}
或
{
0
,
1
,
2
,
2
}
S=\{0,1,1,1,2\}或\{0,1,2,2\}
S={0,1,1,1,2}或{0,1,2,2};否则,
S
=
{
0
,
1
,
1
,
1
,
x
}
,
x
>
3
S=\{0,1,1,1,x\},x>3
S={0,1,1,1,x},x>3。
当
Mex
(
S
)
=
4
\operatorname{Mex}(S)=4
Mex(S)=4 时,
0
,
1
,
2
,
3
∈
S
0,1,2,3\in S
0,1,2,3∈S,则
3
3
3 一定为
S
S
S 的最大值,故
S
=
{
0
,
1
,
1
,
2
,
3
}
S=\{0,1,1,2,3\}
S={0,1,1,2,3}。
当
Mex
(
S
)
>
4
\operatorname{Mex}(S)>4
Mex(S)>4 时,由于
(
n
−
2
)
(
n
−
1
)
2
>
Mex
(
S
)
=
n
\frac{(n-2)(n-1)}{2}>\operatorname{Mex}(S)=n
2(n−2)(n−1)>Mex(S)=n,故无解。
对于操作
4
4
4、
5
5
5、
6
6
6 中集合中的零元素,其可以是任意个。
时间复杂度为
O
(
T
)
\mathcal O(T)
O(T)。
代码
#include<bits/stdc++.h>usingnamespace std;longlong n, k, t;voidread(longlong&x){
x =0;int w =1;char ch =getchar();while(ch <'0'|| ch >'9'){if(ch =='-') w =-1;
ch =getchar();}while(ch >='0'&& ch <='9'){
x =(x <<1)+(x <<3)+ ch -48;
ch =getchar();}
x *= w;}intmain(){read(t);while(t--){longlong ans =0;read(n),read(k);if(k ==2&& n >=1) ans ++;if(k >=4&& n >=1) ans ++;if(k >=5&& n >=2) ans ++;if(k >=4&& n >=2) ans ++;if(k >=5&& n >=3) ans ++;if(n >2&& k >=4) ans +=(n -2);if(n >3&& k >=4) ans +=(n -3);printf("%lld\n", ans);}return0;}