2024/6/28UPD CSDN又擅自给我改VIP文章:(
题面
题目大意
认定一个长度为 n n n 的序列 a a a 是有趣的有且仅当满足以下条件:
- 对于任意一个整数 a i a_i ai,所有严格小于它的数的异或和为 0 0 0。( 假定所有满足条件的数为 b j b_j bj,则异或和为 0 0 0 表示 b 1 x o r b 2 x o r … x o r b j = 0 b_1 \; xor \; b_2 \; xor \; \dots \; xor \; b_j = 0 b1xorb2xor…xorbj=0,xor 表示按位异或 )
请求出满足 ∑ i = 1 n a i = m \sum_{i = 1}^n a_i = m ∑i=1nai=m 的长度为 n n n 有趣的序列。 若有多种构造方式,则任意输出一种即可。
例如: [ 1 , 3 , 2 , 3 , 1 , 2 , 3 ] , [ 4 , 4 , 4 , 4 ] , [ 25 ] [1,3,2,3,1,2,3] , [4,4,4,4] , [25] [1,3,2,3,1,2,3],[4,4,4,4],[25] 是有趣的,而 [ 1 , 2 , 3 , 4 ] ( p 2 = 1 ≠ 0 ) , [ 4 , 1 , 1 , 2 , 4 ] ( p 4 = 1 x o r 1 x o r 2 = 2 ≠ 0 ) , [ 29 , 30 , 30 ] ( p 30 = 29 ≠ 0 ) [1,2,3,4] \; (p_2 = 1 \neq 0), \; [4,1,1,2,4] \; (p_4 = 1 \; xor \; 1 \; xor \; 2 = 2 \neq 0), \; [29,30,30] \; (p_{30} = 29 \neq 0) [1,2,3,4](p2=1=0),[4,1,1,2,4](p4=1xor1xor2=2=0),[29,30,30](p30=29=0)不是有趣的。( 其中 p i p_i pi 表示题目要求中的异或和
)。输入格式
第一行一个整数 T ( 1 ⩽ T ⩽ 1 0 5 ) T \; (1 \leqslant T \leqslant 10^5) T(1⩽T⩽105) ,表示测试样例组数。
对于每组测试样例,包含一行两个整数 n ( 1 ⩽ n ⩽ 1 0 5 ) n \; (1 \leqslant n \leqslant 10^5) n(1⩽n⩽105) 和 m ( 1 ⩽ m ⩽ 1 0 9 ) m \; (1 \leqslant m \leqslant 10^9) m(1⩽m⩽109),含义见题目。
数据保证 ∑ n ⩽ 1 0 5 \sum n \leqslant 10^5 ∑n⩽105。
输出格式
对于每组测试样例,如果第一行为一个字符串。如果存在满足条件的有趣的序列则输出Yes ,否则输出 No。
如果你的输出是 Yes,则接下来的一行包含 n n n 个数,表示你构造的序列,否则不输出这一行。
T r a n s l a t e d b y Z i g h Translated \; by \; Zigh TranslatedbyZigh
分析
首先,如果 m < n m < n m<n 则显然直接输出 No。
其次,如果 n ∣ m n | m n∣m ,那么显然直接输出 n n n 个 m n \frac{m}{n} nm。
剩下的情况我们分四种情况讨论。
- 由于要求异或和为 0 0 0 ,所以所有小于最大数的数都要成对出现,所以当 m m m 为奇数而 n n n 为偶数时直接输出 No,因为无论如何都不能保证除去最大数后都成对出现。
- 而 m m m 为奇数而 n n n 也为奇数时,我们可以直接输出 n − 1 n - 1 n−1 个 1 1 1 和一个 m − ( n − 1 ) m - (n - 1) m−(n−1) 即可。
- m m m 为偶数而 n n n 为奇数时,我们同样可以直接输出 n − 1 n - 1 n−1 个 1 1 1 和一个 m − ( n − 1 ) m - (n - 1) m−(n−1) 。
- m m m 为偶数而 n n n 也为偶数时,我们可以直接输出 n − 2 n - 2 n−2 个 1 1 1 和两个 m − ( n − 2 ) 2 \frac{m - (n - 2)}{2} 2m−(n−2),这样就可以保证除去最大数都成对出现 。
代码
//省略快读和头文件
int T;
int n, m;
int a[MAXN];
int main()
{
T = inpt();
while(T--) {
n = inpt(), m = inpt();
if(m < n) {
puts("No");
continue;
}
if(m % n == 0) {
puts("Yes");
for(int i = 1; i <= n; i++)
printf("%d ", m / n);
puts("");
continue;
}
if(m & 1) {
if((n & 1) == 0) {
puts("No");
continue;
}else {
puts("Yes");
for(int i = 1; i <= n - 1; ++i, --m)
printf("1 ");
printf("%d\n", m);
continue;
}
}else {
if((n & 1) == 0) {
puts("Yes");
int tmp = (m - (n - 2)) >> 1;
for(int i = 1; i <= n - 2; ++i)
printf("1 ");
printf("%d %d\n", tmp, tmp);
continue;
}else {
puts("Yes");
for(int i = 1; i <= n - 1; ++i, --m)
printf("1 ");
printf("%d\n", m);
continue;
}
}
}
return 0;
}
最后再来猜一猜题目翻译里的 Z i g h Zigh Zigh 是谁呢Qwq