Codeforces 1355D Game With Array

题目链接:

https://codeforces.com/contest/1355/problem/D

思路:

结论: S < 2 N S<2N S<2N时Petya会输,否则会赢;
证明:
Case 1:
S ≥ 2 N S\geq2N S2N时,我们选择 ( 1 , 1 , . . . , 1 , S − N + 1 ) (1,1,...,1,S-N+1) (1,1,...,1,SN+1)这个序列(一共有 N − 1 N-1 N1 1 1 1),且令 K = N K=N K=N;
我们需要证明任意子连续的子序列和不等于 N N N S − N S-N SN
(1)如果子序列不包含最后一项 ( S − N + 1 ) (S-N+1) (SN+1),那么子序列和 S 1 S_{1} S1一定小于等于 N − 1 N-1 N1,因此有 S 1 ≤ N − 1 < N ≤ S − N S_1\leq N-1S1N1<NSN
(2)如果包含最后一项,那么子序列和 S 2 S_2 S2必然大于 S − N S-N SN,因此有 N ≤ S − N < S − N + 1 ≤ S 2 N\leq S-NNSN<SN+1S2;
可以看出两种情况序列和都不等于 N N N S − N S-N SN
Case 2:
S < 2 N S<2N S<2N时,证明对于任意序列,都会产生和为 K K K S − K S-K SK的子序列;
设原序列为 { a i } \{a_i\} {ai}
先构造出当 { a i } \{a_i\} {ai}的前缀和数组 { s 1 , s 2 , s 3 , . . . , s n } ( m o d    S ) \{s_1,s_2,s_3,...,s_n\}(mod\; S) {s1,s2,s3,...,sn}(modS),由于 a i > 0 a_i>0 ai>0,因此这是一个元素不重复的数组;我们再构造一个数组 { s 1 + k , s 2 + k , s 3 + k , . . . , s n + k } ( m o d    S ) \{s_1+k,s_2+k,s_3+k,...,s_n+k\}(mod\; S) {s1+k,s2+k,s3+k,...,sn+k}(modS),同理这也是一个元素不重复的数组;
我们知道这两个数组一共有 2 N 2N 2N个元素,而所有元素是属于 [ 0 , S − 1 ] [0,S-1] [0,S1]的,而又因为 S < 2 N S<2N S<2N,因此在这段长为 S S S的区间分布 2 N 2N 2N个元素,它们之间必定有重复,我们又知道同一个数组中不存在重复元素,那么重复元素必定来自不同数组;
(1) s i = s j + K ( j > i ) s_i=s_j+K(j> i) si=sj+K(j>i),则 s j − s i = S − K s_j-s_i=S-K sjsi=SK,即 a i + 1 + . . . + a j = S − K a_{i+1}+...+a_j=S-K ai+1+...+aj=SK
(2) s i = s j + K ( j < i ) s_i=s_j+K(j< i) si=sj+K(j<i),则 s i − s j = K s_i-s_j=K sisj=K,即 a j + 1 + . . . + a i = K a_{j+1}+...+a_i=K aj+1+...+ai=K
从而得证

代码:

#include
#define crr(x) cerr << "#x:" << ' ' << x << '\n';

int main() {
#ifdef MyTest
	freopen("Sakura.txt", "r", stdin);
#endif
	int n, s;
	std::cin >> n >> s;
	if(s < 2 * n) puts("NO");
	else {
		puts("YES");
		for(int i = 0; i < n - 1; ++i) std::cout << 1 << ' ';
		std::cout << s - n + 1 << '\n';
		std::cout << n;	
	}
	return 0;
}

你可能感兴趣的:(Codeforces,#,数学)