[Codeforces] number theory (R1200) Part.2
题单:https://codeforces.com/problemset/page/6?tags=number%20theory,0-1200
299A. Ksusha and Array
原题指路:https://codeforces.com/problemset/problem/299/A
题意 ( 2 s ) (2\ \mathrm{s}) (2 s)
给定一个长度为 n ( 1 ≤ n ≤ 1 e 5 ) n\ \ (1\leq n\leq 1\mathrm{e}5) n (1≤n≤1e5)的序列 a 1 , ⋯ , a n ( 1 ≤ a i ≤ 1 e 9 ) a_1,\cdots,a_n\ \ (1\leq a_i\leq 1\mathrm{e}9) a1,⋯,an (1≤ai≤1e9),在其中找一个$a_i\ s.t.\ 序列中所有数都是它的倍数 , 若不存在 , 输出 序列中所有数都是它的倍数,若不存在,输出 序列中所有数都是它的倍数,若不存在,输出-1$.
思路
只需判断序列的 gcd \gcd gcd是否在序列中出现过即可.
代码
void solve() {
int n; cin >> n;
n--;
uset<int> s;
int ans; cin >> ans;
s.insert(ans);
while (n--) {
int x; cin >> x;
s.insert(x);
ans = gcd(ans, x);
}
cout << (s.count(ans) ? ans : -1);
}
int main() {
solve();
}
313A. Ilya and Bank Account
原题指路:https://codeforces.com/problemset/problem/313/A
题意 ( 2 s ) (2\ \mathrm{s}) (2 s)
给定一个整数 n ( 10 ≤ ∣ n ∣ ≤ 1 e 9 ) n\ \ (10\leq |n|\leq 1\mathrm{e}9) n (10≤∣n∣≤1e9),每次操作可删除其的最后一个数码或倒数第二个数码.问至多进行一次操作后能得到的最大数.
思路
原数、删除最后一个数码、删除倒数第二个数码三个数取 max \max max即可.
代码
void solve() {
int n; cin >> n;
cout << max({ n,n / 10,n / 100 * 10 + n % 10 });
}
int main() {
solve();
}
361B. Levko and Permutation
原题指路:https://codeforces.com/problemset/problem/361/B
题意
给定两整数 n , k ( 1 ≤ n ≤ 1 e 5 , 0 ≤ k ≤ n ) n,k\ \ (1\leq n\leq 1\mathrm{e}5,0\leq k\leq n) n,k (1≤n≤1e5,0≤k≤n),构造一个 1 ∼ n 1\sim n 1∼n的排列 p 1 , ⋯ , p n p_1,\cdots,p_n p1,⋯,pn,使得其中恰有 k k k个元素满足 gcd ( i , p i ) > 1 \gcd(i,p_i)>1 gcd(i,pi)>1.若不存在,输出 − 1 -1 −1.
思路
显然 k = n k=n k=n时无解,其余情况有解.构造一个排列,使得其最后 k k k个元素符合条件,前面的 ( n − k ) (n-k) (n−k)个元素不符合条件即可.
代码
void solve() {
int n, k; cin >> n >> k;
if (k == n) {
cout << -1;
return;
}
cout << n - k << ' ';
for (int i = 1; i <= n; i++)
if (i != n - k) cout << i << ' ';
}
int main() {
solve();
}
456B. Fedya and Maths
原题指路:https://codeforces.com/problemset/problem/456/B
题意
给定整数 n ( 0 ≤ n ≤ 1 0 1 0 5 ) n\ \ (0\leq n\leq 10^{10^5}) n (0≤n≤10105),求 ( 1 n + 2 n + 3 n + 4 n ) m o d 5 (1^n+2^n+3^n+4^n)\ \mathrm{mod}\ 5 (1n+2n+3n+4n) mod 5.
思路I
注意到 ( 1 n + 2 n + 3 n + 4 n ) m o d 5 = ( 1 n m o d 5 ) + ( 2 n m o d 5 ) + ( 3 n m o d 5 ) + ( 4 n m o d 5 ) (1^n+2^n+3^n+4^n)\ \mathrm{mod}\ 5=(1^n\ \mathrm{mod}\ 5)+(2^n\ \mathrm{mod}\ 5)+(3^n\ \mathrm{mod}\ 5)+(4^n\ \mathrm{mod}\ 5) (1n+2n+3n+4n) mod 5=(1n mod 5)+(2n mod 5)+(3n mod 5)+(4n mod 5),只需考察 2 n , 3 n , 4 n 2^n,3^n,4^n 2n,3n,4n在模 5 5 5下何时出现循环.
2 0 m o d 5 ≡ 1 , 2 1 m o d 5 ≡ 2 , 2 2 m o d 5 ≡ 4 , 2 3 m o d 5 ≡ 3 , 2 4 m o d 5 ≡ 1 2^0\ \mathrm{mod}\ 5\equiv 1,2^1\ \mathrm{mod}\ 5\equiv 2,2^2\ \mathrm{mod}\ 5\equiv 4,2^3\ \mathrm{mod}\ 5\equiv 3,2^4\ \mathrm{mod}\ 5\equiv 1 20 mod 5≡1,21 mod 5≡2,22 mod 5≡4,23 mod 5≡3,24 mod 5≡1,考察 n m o d 4 n\ \mathrm{mod}\ 4 n mod 4即可.
3 0 m o d 5 ≡ 1 , 3 1 m o d 5 ≡ 3 , 3 2 m o d 5 ≡ 4 , 3 3 m o d 5 ≡ 2 , 3 4 m o d 5 ≡ 1 3^0\ \mathrm{mod}\ 5\equiv 1,3^1\ \mathrm{mod}\ 5\equiv 3,3^2\ \mathrm{mod}\ 5\equiv 4,3^3\ \mathrm{mod}\ 5\equiv 2,3^4\ \mathrm{mod}\ 5\equiv 1 30 mod 5≡1,31 mod 5≡3,32 mod 5≡4,33 mod 5≡2,34 mod 5≡1,考察 n m o d 4 n\ \mathrm{mod}\ 4 n mod 4即可.
4 0 m o d 5 ≡ 1 , 4 1 m o d 5 ≡ 4 , 4 2 m o d 5 ≡ 1 4^0\ \mathrm{mod}\ 5\equiv 1,4^1\ \mathrm{mod}\ 5\equiv 4,4^2\ \mathrm{mod}\ 5\equiv 1 40 mod 5≡1,41 mod 5≡4,42 mod 5≡1,考察 n m o d 2 n\ \mathrm{mod}\ 2 n mod 2即可.
代码I
int get(string s, int mod) { // 大数取模
int res = 0;
for (auto ch : s)
res = ((ll)res * 10 % mod + ch - '0') % mod;
return res;
}
void solve() {
string s; cin >> s;
int ans = 1; // 1^n mod 5 = 1
switch (get(s, 4)) {
case 0: ans += 1; break;
case 1: ans += 2; break;
case 2: ans += 4; break;
case 3: ans += 3; break;
}
switch (get(s, 4)) {
case 0: ans += 1; break;
case 1: ans += 3; break;
case 2: ans += 4; break;
case 3: ans += 2; break;
}
switch (get(s, 2)) {
case 0: ans += 1; break;
case 1: ans += 4; break;
}
cout << ans % 5;
}
int main() {
solve();
}
思路II
因 gcd ( 1 , 5 ) = gcd ( 2 , 5 ) = gcd ( 3 , 5 ) = gcd ( 4 , 5 ) = 1 \gcd(1,5)=\gcd(2,5)=\gcd(3,5)=\gcd(4,5)=1 gcd(1,5)=gcd(2,5)=gcd(3,5)=gcd(4,5)=1,由扩展Euler定理:
( 1 n + 2 n + 3 n + 4 n ) m o d 5 = ( 1 n m o d φ ( n ) + 2 n m o d φ ( n ) + 3 n m o d φ ( n ) + 4 n m o d φ ( n ) ) m o d 5 (1^n+2^n+3^n+4^n)\ \mathrm{mod}\ 5=\left(1^{n\ \mathrm{mod}\ \varphi(n)}+2^{n\ \mathrm{mod}\ \varphi(n)}+3^{n\ \mathrm{mod}\ \varphi(n)}+4^{n\ \mathrm{mod}\ \varphi(n)}\right)\ \mathrm{mod}\ 5 (1n+2n+3n+4n) mod 5=(1n mod φ(n)+2n mod φ(n)+3n mod φ(n)+4n mod φ(n)) mod 5,
而 φ ( 5 ) = 4 \varphi(5)=4 φ(5)=4,故 原式 = ( 1 n m o d 4 + 2 n m o d 4 + 3 n m o d 4 + 4 n m o d 4 ) m o d 5 原式=\left(1^{n\ \mathrm{mod}\ 4}+2^{n\ \mathrm{mod}\ 4}+3^{n\ \mathrm{mod}\ 4}+4^{n\ \mathrm{mod}\ 4}\right)\ \mathrm{mod}\ 5 原式=(1n mod 4+2n mod 4+3n mod 4+4n mod 4) mod 5.
代码II
int get(string s, int mod) { // 大数取模
int res = 0;
for (auto ch : s)
res = ((ll)res * 10 % mod + ch - '0') % mod;
return res;
}
void solve() {
string s; cin >> s;
int t = get(s, 4);
int ans = 1 + qpow(2, t, 5) + qpow(3, t, 5) + qpow(4, t, 5);
cout << ans % 5;
}
int main() {
solve();
}
472A. Design Tutorial: Learn from Math
原题指路:https://codeforces.com/problemset/problem/472/A
题意
给定一个整数 n ( 12 ≤ n ≤ 1 e 6 ) n\ \ (12\leq n\leq 1\mathrm{e}6) n (12≤n≤1e6),将其表示为两合数之和.
思路
① n n n为奇数时, n = 9 + ( n − 9 ) n=9+(n-9) n=9+(n−9)符合题意,因为 n − 9 ≥ 4 n-9\geq 4 n−9≥4且 ( n − 9 ) (n-9) (n−9)是偶数.
② n n n为偶数时, n = 8 + ( n − 8 ) n=8+(n-8) n=8+(n−8)符合题意,因为 n − 8 ≥ 4 n-8\geq 4 n−8≥4且 ( n − 8 ) (n-8) (n−8)是偶数.
代码
void solve() {
int n; cin >> n;
if (n & 1) cout << 9 << ' ' << n - 9;
else cout << 8 << ' ' << n - 8;
}
int main() {
solve();
}
483A. Counterexample
原题指路:https://codeforces.com/problemset/problem/483/A
题意
给定两整数 l , r ( 1 ≤ l ≤ r ≤ 1 e 18 , r − l ≤ 50 ) l,r\ \ (1\leq l\leq r\leq 1\mathrm{e}18,r-l\leq 50) l,r (1≤l≤r≤1e18,r−l≤50),求三个整数 a , b , c ∈ [ l , r ] s . t . gcd ( a , b ) = gcd ( b , c ) = 1 , gcd ( a , c ) ≠ 1 a,b,c\in[l,r]\ s.t.\ \gcd(a,b)=\gcd(b,c)=1,\gcd(a,c)\neq 1 a,b,c∈[l,r] s.t. gcd(a,b)=gcd(b,c)=1,gcd(a,c)=1.
思路
若区间内的数的个数 < 3 <3 <3,则无解.
注意到若 l l l为偶数,可取相邻的 l , l + 1 , l + 2 l,l+1,l+2 l,l+1,l+2,此时 gcd ( l , l + 2 ) = 2 ≠ 1 \gcd(l,l+2)=2\neq 1 gcd(l,l+2)=2=1. l l l为奇数时, + 1 +1 +1统一为偶数即可.
代码
void solve() {
ll l, r; cin >> l >> r;
if (l & 1) l++; // 保证l是偶数
if (r - l + 1 < 3) cout << -1;
else cout << l << ' ' << l + 1 << ' ' << l + 2;
}
int main() {
solve();
}
577A. Multiplication Table
原题指路:https://codeforces.com/problemset/problem/577/A
题意
给定一个 n × n n\times n n×n的网格,下标从 1 1 1开始,其中格子 ( i , j ) (i,j) (i,j)中的数为 i ⋅ j i\cdot j i⋅j.给定两整数 n , x ( 1 ≤ n ≤ 1 e 5 , 1 ≤ x ≤ 1 e 9 ) n,x\ \ (1\leq n\leq 1\mathrm{e}5,1\leq x\leq 1\mathrm{e}9) n,x (1≤n≤1e5,1≤x≤1e9),求该网格中 x x x出现的次数.
思路
即求 1 ∼ n 1\sim n 1∼n中有多少对不同的 ( i , j ) s . t . i j = x (i,j)\ s.t.\ ij=x (i,j) s.t. ij=x,暴力即可.
代码
void solve() {
int n, x; cin >> n >> x;
ll ans = 0;
for (int i = 1; i <= n; i++) {
if (x % i == 0) {
int j = x / i;
if (j <= n) ans++;
}
}
cout << ans;
}
int main() {
solve();
}
630A. Again Twenty Five!
原题指路:https://codeforces.com/problemset/problem/630/A
题意 ( 0.5 s 0.5\ \mathrm{s} 0.5 s)
给定 n ( 2 ≤ n ≤ 2 e 18 ) n\ \ (2\leq n\leq 2\mathrm{e}18) n (2≤n≤2e18),求 5 n 5^n 5n的末两位.
思路I
因 gcd ( 5 , 100 ) ≠ 1 , φ ( 100 ) = 40 \gcd(5,100)\neq 1,\varphi(100)=40 gcd(5,100)=1,φ(100)=40,由扩展Euler定理: a n s = 5 n m o d 100 = { 5 n m o d 100 , n < 40 5 n m o d 40 + 40 m o d 100 , n ≥ 40 ans=5^n\ \mathrm{mod}\ 100=\begin{cases}5^n\ \mathrm{mod}\ 100,n<40 \\ 5^{n\ \mathrm{mod}\ 40+40}\ \mathrm{mod}\ 100,n\geq 40\end{cases} ans=5n mod 100={5n mod 100,n<405n mod 40+40 mod 100,n≥40.
代码II
void solve() {
ll n; cin >> n;
if (n < 40) cout << qpow(5, n, 100);
else cout << qpow(5, n % 40 + 40, 100);
}
int main() {
solve();
}
思路II
注意到 5 n m o d 100 = [ ( 5 n − 1 m o d 100 ) ⋅ 5 ] m o d 100 5^n\ \mathrm{mod}\ 100=[(5^{n-1}\ \mathrm{mod}\ 100)\cdot 5]\ \mathrm{mod}\ 100 5n mod 100=[(5n−1 mod 100)⋅5] mod 100,
而 5 2 = 25 , 5 3 m o d 100 = [ ( 5 2 m o d 100 ) ⋅ 5 ] m o d 100 = ( 25 ⋅ 5 ) m o d 100 = 25 5^2=25,5^3\ \mathrm{mod}\ 100=[(5^2\ \mathrm{mod}\ 100)\cdot 5]\ \mathrm{mod}\ 100=(25\cdot 5)\ \mathrm{mod}\ 100=25 52=25,53 mod 100=[(52 mod 100)⋅5] mod 100=(25⋅5) mod 100=25,
5 4 m o d 100 = [ ( 5 3 m o d 100 ) ⋅ 5 ] m o d 100 = ( 25 ⋅ 5 ) m o d 100 = 25 5^4\ \mathrm{mod}\ 100=[(5^3\ \mathrm{mod}\ 100)\cdot 5]\ \mathrm{mod}\ 100=(25\cdot 5)\ \mathrm{mod}\ 100=25 54 mod 100=[(53 mod 100)⋅5] mod 100=(25⋅5) mod 100=25,故 5 n m o d 100 = 25 ( n ≥ 2 ) 5^n\ \mathrm{mod}\ 100=25\ \ (n\geq 2) 5n mod 100=25 (n≥2).
代码II
void solve() {
ll n; cin >> n;
cout << 25;
}
int main() {
solve();
}
630J. Divisibility
原题指路:https://codeforces.com/problemset/problem/630/J
题意 ( 0.5 s 0.5\ \mathrm{s} 0.5 s)
给定一个整数 n ( 1 ≤ n ≤ 1 e 18 ) n\ \ (1\leq n\leq 1\mathrm{e}18) n (1≤n≤1e18),求 [ 1 , n ] [1,n] [1,n]中有几个数能被 [ 2 , 10 ] [2,10] [2,10]中的所有整数整除.
思路
2 = 2 , 3 = 3 , 4 = 2 2 , 5 = 5 , 6 = 2 ⋅ 3 , 7 = 7 , 8 = 2 3 , 9 = 3 2 , 10 = 2 ⋅ 5 2=2,3=3,4=2^2,5=5,6=2\cdot 3,7=7,8=2^3,9=3^2,10=2\cdot 5 2=2,3=3,4=22,5=5,6=2⋅3,7=7,8=23,9=32,10=2⋅5,故能被 [ 2 , 10 ] [2,10] [2,10]中所有数整除的数是 2 3 ⋅ 3 2 ⋅ 5 ⋅ 7 = 2520 2^3\cdot 3^2\cdot 5\cdot 7=2520 23⋅32⋅5⋅7=2520的倍数,故 a n s = ⌊ n 2520 ⌋ ans=\left\lfloor\dfrac{n}{2520}\right\rfloor ans=⌊2520n⌋.
代码
void solve() {
ll n; cin >> n;
cout << n / 2520;
}
int main() {
solve();
}
633A. Ebony and Ivory
原题指路:https://codeforces.com/problemset/problem/633/A
题意 ( 2 s 2\ \mathrm{s} 2 s)
给定三个整数 a , b , c ( 1 ≤ a , b ≤ 100 , 1 ≤ c ≤ 1 e 4 ) a,b,c\ \ (1\leq a,b\leq 100,1\leq c\leq 1\mathrm{e}4) a,b,c (1≤a,b≤100,1≤c≤1e4),问不定方程 a x + b y = c ax+by=c ax+by=c是否有非负整数解 ( x , y ) (x,y) (x,y).
思路I
显然不定方程 a x + b y = c ax+by=c ax+by=c有整数解的充要条件是 gcd ( a , b ) ∣ c \gcd(a,b)\mid c gcd(a,b)∣c.
先用扩展Euclid算法求不定方程 a x + b y = gcd ( a , b ) = d ax+by=\gcd(a,b)=d ax+by=gcd(a,b)=d的一组解 ( x ′ , y ′ ) (x',y') (x′,y′),则不定方程 a x + b y = c ax+by=c ax+by=c的一组特解是 ( x 0 , y 0 ) = ( x ′ c d , y ′ c d ) (x_0,y_0)=\left(\dfrac{x'c}{d},\dfrac{y'c}{d}\right) (x0,y0)=(dx′c,dy′c),通解为 ( x 0 − k ⋅ b d , y 0 + k ⋅ a d ) ( k ∈ Z ) \left(x_0-k\cdot \dfrac{b}{d},y_0+k\cdot \dfrac{a}{d}\right)\ \ (k\in\mathbb{Z}) (x0−k⋅db,y0+k⋅da) (k∈Z).
若不定方程 a x + b y = d ax+by=d ax+by=d有非负整数解,则 { x 0 − k ⋅ b d ≥ 0 y 0 + k ⋅ a d ≥ 0 \begin{cases}x_0-k\cdot\dfrac{b}{d}\geq 0 \\ y_0+k\cdot\dfrac{a}{d}\geq 0 \end{cases} ⎩ ⎨ ⎧x0−k⋅db≥0y0+k⋅da≥0,解得 { k ≤ ⌊ d x 0 b ⌋ − k ≤ ⌊ d y 0 a ⌋ \begin{cases}k\leq \left\lfloor\dfrac{dx_0}{b}\right\rfloor \\ -k\leq\left\lfloor\dfrac{dy_0}{a}\right\rfloor\end{cases} ⎩ ⎨ ⎧k≤⌊bdx0⌋−k≤⌊ady0⌋,两式相加得: ⌊ d x 0 b ⌋ + ⌊ d y 0 a ⌋ ≥ 0 \left\lfloor\dfrac{dx_0}{b}\right\rfloor+\left\lfloor\dfrac{dy_0}{a}\right\rfloor\geq 0 ⌊bdx0⌋+⌊ady0⌋≥0.
代码II
int exgcd(int a, int b, int& x, int& y) {
if (!b) {
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
void solve() {
int a, b, c; cin >> a >> b >> c;
int x, y;
int d = exgcd(a, b, x, y); // 求ax+by=gcd(a,b)的解(x,y)
if (c % d) cout << "NO";
else {
x *= c / d, y *= c / d; // 变为ax+by=c的解(x,y)
if (floor((double)d * x / b) + floor((double)d * y / a) >= 0) cout << "YES";
else cout << "NO";
}
}
int main() {
solve();
}
思路II
a , b , c a,b,c a,b,c的范围都很小,暴力即可.
代码II
void solve() {
int a, b, c; cin >> a >> b >> c;
for (int x = 0; x <= 10000; x++) {
if (c >= a * x && (c - a * x) % b == 0) {
cout << "YES";
return;
}
}
cout << "NO";
}
int main() {
solve();
}