赞
踩
题意: 有n个数,可以进行一种操作得到 2 x − y 2x - y 2x−y, 原数不会消失,问能否得到k
就没思路,就嗯罚坐
主要是感觉找不到那个性质,没有想到要把两两合在一起看,就只看了单个数,搁那构造,害构造不明白,大晚上的贼困
看了网上题解,
能发现 2x-y 取2个数得到的都是系数和为1 的式子(eg : 4x - 3y),取4个数看一下情况:
2
×
(
2
×
x
−
y
)
−
(
2
×
p
−
q
)
2 \times (2 \times x-y)-(2 \times p-q)
2×(2×x−y)−(2×p−q),即:
x
+
(
x
−
p
)
+
2
(
x
−
y
)
−
(
p
−
q
)
x+(x-p)+2(x-y)-(p-q)
x+(x−p)+2(x−y)−(p−q),再多推推(
可以得到的值的范围是
(
a
i
−
a
j
)
(a_i - a_j)
(ai−aj)经过线性组合后与
a
p
a_p
ap的和能取到的所有数,判断k是否在这个范围内即可。
n个数的裴蜀定理 (我前两天刚被这个知识点的题卡过我怎么又
(
a
i
−
a
j
)
(a_i - a_j)
(ai−aj) 可以由相邻两项的差 线性得到
若
k
−
a
p
k - a_p
k−ap 可以由
(
a
i
−
a
j
)
(a_i - a_j)
(ai−aj) 线性得到则说明能得到
然后就是套裴蜀定理,
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N = 2e5 + 10; ll a[N]; int main() { int T; cin >> T; while(T--) { ll n, k; cin >> n >> k; for(int i = 1; i <= n; ++ i) { cin >> a[i]; } ll d = 0; for(int i = 2; i <= n; ++ i) { d = __gcd(d, a[i] - a[i - 1]); } bool f = 0; for(int i = 1; i <= n; ++ i) { if((k - a[i]) % d == 0) { f = 1; break; } } if(f) { puts("YES"); } else { puts("NO"); } } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。