赞
踩
(这题我就不给翻译了吧)
求众数的出现次数即可
给定数 d ( 1 ≤ d ≤ 9 ) d(1\leq d \leq 9) d(1≤d≤9),如果一个数的十进制表示中的某一位为 d d d,则这个数是“幸运数”。给定 q ( 1 ≤ q ≤ 1 0 4 ) q(1\leq q\leq 10^4) q(1≤q≤104)个数 a 1 , a 2 , a 3 , . . . , a q ( 1 ≤ a i ≤ 1 0 9 ) a_1,a_2,a_3,...,a_q(1\leq a_i \leq 10^9) a1,a2,a3,...,aq(1≤ai≤109),对其中的每一个数,判断是否可以表示成一个或多个幸运数的和。
首先给出结论:如果 a i a_i ai大于 10 d 10d 10d,那么 a i a_i ai一定可以表示成幸运数的和。(我知道的最紧的上界了,好像听说 9 d 9d 9d就有反例,所以这个应该是上确界)
证明:
对于一个大于10d的数,它显然可以表示成
k
d
+
r
(
k
≥
10
,
0
≤
m
≤
9
)
kd+r\quad(k\geq 10,0\leq m \leq 9)
kd+r(k≥10,0≤m≤9)的形式,进而可以表示为
10
d
+
r
+
(
k
−
10
)
d
(
k
≥
10
,
0
≤
m
≤
9
)
10d+r+(k-10)d\quad(k\geq 10,0\leq m \leq 9)
10d+r+(k−10)d(k≥10,0≤m≤9)的形式。
观察上式,
10
d
+
r
10d+r
10d+r显然是幸运数,
(
k
−
10
)
d
(k-10)d
(k−10)d也是幸运数,即可以表示成两个幸运数的和。
接着其实可以证明这是确界,如果取
9
d
9d
9d,
d
=
8
,
a
i
=
73
d=8,a_i=73
d=8,ai=73就是一个反例。所以10d是最小的。
判断:
对于大于
10
d
10d
10d的数,我们有上述结论。对于小于
10
d
10d
10d的数,可以暴力判断:每次减
d
d
d,判断是否有那个数位上为
d
d
d,直到小于
d
d
d。
回头再写
给定 n ( 2 ≤ n ≤ 2 ⋅ 1 0 5 ) n(2\leq n \leq 2\cdot10^5) n(2≤n≤2⋅105)个数 x 1 , x 2 , . . . , x n ( − 1 0 18 ≤ x i ≤ 1 0 18 ) x_1,x_2,...,x_n(-10^{18}\leq x_i\leq 10^{18}) x1,x2,...,xn(−1018≤xi≤1018),以及一个数 k ( − 1 0 18 ≤ k ≤ 1 0 18 ) k(-10^{18}\leq k\leq 10^{18}) k(−1018≤k≤1018)。每次可以从 x 1 , x 2 , . . . , x n x_1,x_2,...,x_n x1,x2,...,xn中选择两个数 x , y x,y x,y(可以相同),计算出 2 x − y 2x-y 2x−y再放回去(连同算出的 2 x − y 2x-y 2x−y一并放回去),判断是否可以凑出 k k k
先贴两个别的D题题解。[传送门1][传送门2]原本我D题就打算按照线性组合的思路做,但是没做出来。
这里按照官方题解的思路走:这是一道裴蜀定理的题。
首先给出裴蜀定理:对于关于
x
,
y
x,y
x,y的不定方程
a
x
+
b
y
=
c
ax+by=c
ax+by=c当且仅当
g
c
d
(
a
,
b
)
∣
c
gcd(a,b)|c
gcd(a,b)∣c时有解。
并可以推广到任意个整数:
a
1
x
1
+
a
2
x
2
+
.
.
.
+
a
n
x
n
=
c
a_1x_1+a_2x_2+...+a_nx_n=c
a1x1+a2x2+...+anxn=c当且仅当
g
c
d
(
a
1
,
a
2
,
.
.
.
,
a
n
)
∣
c
gcd(a_1,a_2,...,a_n)|c
gcd(a1,a2,...,an)∣c时有解。
思路:
k
=
2
x
−
y
k=2x-y
k=2x−y也可以写成
k
=
x
+
(
x
−
y
)
k=x+(x-y)
k=x+(x−y),即表示成一个数加上它与另一个数的差。
事实上,一个可以多次通过
2
x
−
y
2x-y
2x−y表示出的数一定可以表示成另一个可表示出的数
k
′
k'
k′与多组差的和:
k = k ′ + ∑ i , j c ( x i − x j ) ( c 为 常 系 数 ) k=k'+\sum_{i,j}c(x_i-x_j)(c为常系数) k=k′+i,j∑c(xi−xj)(c为常系数)
举个例子:设
k
1
k
2
k_1k_2
k1k2由
x
i
,
x
j
,
x
p
,
x
q
x_i,x_j,x_p,x_q
xi,xj,xp,xq表示,即:
k
1
=
x
i
+
(
x
i
−
x
j
)
,
k
2
=
x
p
+
(
x
p
−
x
q
)
k1=xi+(xi−xj),k2=xp+(xp−xq)
那么
k
1
k
2
k_1k_2
k1k2表示的数为:
k
=
2
k
1
−
k
2
=
x
i
+
(
x
i
−
x
j
)
+
[
2
(
x
i
−
x
p
)
+
(
x
q
−
x
j
)
]
=
k
′
+
∑
i
,
j
c
(
x
i
−
x
j
)
(
c
为
常
系
数
)
k=2k1−k2=xi+(xi−xj)+[2(xi−xp)+(xq−xj)]=k′+∑i,jc(xi−xj)(c为常系数)
上式还能继续化简:
k
=
k
′
+
∑
i
,
j
c
(
x
i
−
x
j
)
k
′
=
k
′
′
+
∑
i
,
j
c
(
x
i
−
x
j
)
.
.
.
k
(
m
)
=
x
p
+
∑
i
,
j
c
(
x
i
−
x
j
)
k=k′+∑i,jc(xi−xj)k′=k″+∑i,jc(xi−xj)...k(m)=xp+∑i,jc(xi−xj)
得
k
=
x
p
+
∑
i
,
j
c
(
x
i
−
x
j
)
=
x
1
+
(
x
p
−
x
1
)
+
∑
i
,
j
c
(
x
i
−
x
j
)
=
x
1
+
∑
i
,
j
c
(
x
i
−
x
j
)
k=xp+∑i,jc(xi−xj)=x1+(xp−x1)+∑i,jc(xi−xj)=x1+∑i,jc(xi−xj)
而我们想要
k
=
x
1
+
∑
i
,
j
c
(
x
i
−
x
j
)
k=x_1+\sum_{i,j}c(x_i-x_j)
k=x1+∑i,jc(xi−xj),也即
∑
i
,
j
c
(
x
i
−
x
j
)
=
k
−
x
1
\sum_{i,j}c(x_i-x_j)=k-x_1
∑i,jc(xi−xj)=k−x1。
也就是
k
−
x
1
k-x_1
k−x1能否用两个数的差值表示。也就转化到了裴蜀定理,如果所有差值的最大公约数能够整除
k
−
x
1
k-x_1
k−x1,那么就能够凑出
k
k
k
判断:
虽然能够做到这很不容易,但到这步得到的结论依然不尽如人意。如果真就按照上面思路,那我们需要求出任意两个数的差值。在
n
(
2
≤
n
≤
2
⋅
1
0
5
)
n(2\leq n \leq 2\cdot10^5)
n(2≤n≤2⋅105)的要求下显然可能是正解。
那么应该怎么优化呢?
考虑下式:
g
c
d
(
a
,
b
,
a
+
b
)
=
g
c
d
(
a
,
b
)
gcd(a,b,a+b)=gcd(a,b)
gcd(a,b,a+b)=gcd(a,b)。
证明十分显然,如果
g
c
d
(
a
,
b
)
=
g
gcd(a,b)=g
gcd(a,b)=g,那么有
g
∣
a
,
g
∣
b
g|a,g|b
g∣a,g∣b,显然也有
g
∣
(
a
+
b
)
g|(a+b)
g∣(a+b)。所以
g
c
d
(
a
,
b
,
a
+
b
)
=
g
c
d
(
a
,
b
)
gcd(a,b,a+b)=gcd(a,b)
gcd(a,b,a+b)=gcd(a,b)
那么,如果我们求出了 x 2 − x 1 , x 3 − x 2 x_2-x_1,x_3-x_2 x2−x1,x3−x2的 g c d gcd gcd,也就相当于求得了 x 2 − x 1 , x 3 − x 2 , x 3 − x 1 x_2-x_1,x_3-x_2,x_3-x_1 x2−x1,x3−x2,x3−x1的 g c d gcd gcd。推广一下,只要我们求出 x 2 − x 1 , x 3 − x 2 , x n − x n − 1 x_2-x_1,x_3-x_2,x_n-x_{n-1} x2−x1,x3−x2,xn−xn−1的 g c d gcd gcd,也就相当于求出来任意两数之差的 g c d gcd gcd
于是就可以判断: g c d ( x 2 − x 1 , x 3 − x 2 , . . . , x n − x n − 1 ) gcd(x_2-x_1, x_3-x_2,...,x_n-x_{n-1}) gcd(x2−x1,x3−x2,...,xn−xn−1)是否整除 k − x 1 k-x_1 k−x1即可:
最后给出AC代码:
#include <bits/stdc++.h> using namespace std; const int maxn = 2e5 + 10; typedef long long ll; ll x[maxn]; ll gcd(ll a, ll b) { while (b) { ll tmp = a % b; a = b; b = tmp; } return a; } int main() { int t; scanf("%d", &t); while (t--) { int n; ll k; scanf("%lld%lld", &n, &k); for (int i = 0; i < n; i++) { scanf("%lld", &x[i]); } sort(x, x + n); ll g = 0; for (int i = 1; i < n; i++) { g = gcd(g, x[i] - x[i - 1]); } if ((k - x[0]) % g) { printf("NO\n"); } else { printf("YES\n"); } } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。