All the number theory knowledge involved below proves portal 1
All the number theory knowledge involved below proves Portal 2
C Looooops
description
solution
Transform the meaning of the question into a mathematical formula A + C x ≡ B ( m o d 2 k ) A+Cx\equiv B\pmod {2^k} A+Cx ≡ B(mod2k), and finally find the minimum x x x
In fact, removing the mold taking operation is an extension of the very template Euclid, C ⋅ x − y ⋅ 2 k = B − A C·x-y·2^k=B-A C⋅x−y⋅2k=B−A
First find a set of special solutions, and then find the minimum positive integer x x x (please send the minimum solution to the certification chapter)
code
#include <cmath> #include <cstdio> #include <iostream> using namespace std; #define int long long int exgcd( int a, int b, int &x, int &y ) { if( ! b ) { x = 1, y = 0; return a; } else { int d = exgcd( b, a % b, y, x ); y -= ( a / b ) * x; return d; } } signed main() { int A, B, C, k; while( scanf( "%lld %lld %lld %lld", &A, &B, &C, &k ) ) { if( ! A && ! B && ! C && ! k ) break; int a = C, b = 1ll << k, c = B - A, x, y; int d = exgcd( a, b, x, y ); if( c % d ) { printf( "FOREVER\n" ); continue; } x = ( x * ( c / d ) % ( b / d ) + ( b / d ) ) % ( b / d ); printf( "%lld\n", x ); } return 0; }
Checkers
description
solution
The key to this question is that only one chess piece is allowed to be skipped at a time
That is, for the chess pieces in the middle, only the closest chess pieces have the right to jump
a,b,c → \rightarrow →b,2b-a,c/a,2b-c,b
If will ( a , b , c ) (a,b,c) (a,b,c) is regarded as a point, then a point can only have two successors
Build a binary tree, jump all relative to the middle chess pieces, reduce the distance of three balls until they are equal, and define such points as the root of the tree
To judge that there is no solution, you only need to see whether the initial situation and the end situation belong to the same node after operating according to the above rules
Jumping once is to climb a layer on the tree. You can't climb step by step, but jump to a point with a shorter distance at one time, and then jump on the other side
Then count how many steps the situation jumps in this process, that is, the corresponding depth
Jump the initial situation and the end situation to the same level first, and then find the depth of two-point jump l c a lca lca (same for both sides)
code
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; #define int long long #define inf 1e18 struct node { int pos[5]; bool operator != ( const node &t ) const { for( int i = 1;i <= 3;i ++ ) if( pos[i] != t.pos[i] ) return 1; return 0; } }S, E; int dep_S, dep_E, dep; int Sp[5], Ep[5]; node solve( int MS[], int len ) { node ans; for( int i = 1;i <= 3;i ++ ) ans.pos[i] = MS[i]; int d1 = MS[2] - MS[1], d2 = MS[3] - MS[2]; if( d1 == d2 ) return ans; else if( d1 < d2 ) { int k = min( len, ( d2 - 1 ) / d1 ); len -= k, dep += k; ans.pos[1] += k * d1; ans.pos[2] += k * d1; } else { int k = min( len, ( d1 - 1 ) / d2 ); len -= k, dep += k; ans.pos[2] -= k * d2; ans.pos[3] -= k * d2; } if( len ) return solve( ans.pos, len ); else return ans; } signed main() { for( int i = 1;i <= 3;i ++ ) scanf( "%lld", &Sp[i] ); for( int i = 1;i <= 3;i ++ ) scanf( "%lld", &Ep[i] ); sort( Sp + 1, Sp + 4 ); sort( Ep + 1, Ep + 4 ); S = solve( Sp, inf ); dep_S = dep; dep = 0; E = solve( Ep, inf ); dep_E = dep; dep = 0; if( S != E ) return ! printf( "NO\n" ); else printf( "YES\n" ); if( dep_S > dep_E ) { swap( dep_S, dep_E ); for( int i = 1;i <= 3;i ++ ) swap( Sp[i], Ep[i] ); } int ans = dep_E - dep_S; if( ans ) { E = solve( Ep, ans ); for( int i = 1;i <= 3;i ++ ) Ep[i] = E.pos[i]; } int l = 0, r = dep_S; while( l < r ) { int mid = ( l + r ) >> 1; if( solve( Sp, mid ) != solve( Ep, mid ) ) l = mid + 1; else r = mid; } printf( "%lld\n", ans + l * 2 ); return 0; }
The Luckiest number
description
solution
L ∣ 8 ∗ 1 0 n − 1 9 ⇔ 9 ∗ L gcd ( 8 , L ) ∣ ( 10 n − 1 ) ∗ 8 gcd ( 8 , L ) L\bigg|8*\frac{10^n-1}{9}\Leftrightarrow \frac{9*L}{\gcd(8,L)}\bigg|\frac{(10n-1)*8}{\gcd(8,L)} L∣∣∣∣8∗910n−1⇔gcd(8,L)9∗L∣∣∣∣gcd(8,L)(10n−1)∗8
∵ gcd ( 8 , 9 ) = 1 \because \gcd(8,9)=1 ∵gcd(8,9)=1
∴ 10 n ≡ 1 ( m o d 9 L gcd ( 8 , L ) ) \therefore 10n\equiv 1\pmod{\frac{9L}{\gcd(8,L)}} ∴10n≡1(modgcd(8,L)9L)
No solution, i.e gcd ( 10 , 9 L gcd ( 8 , L ) ) = 1 \gcd(10,\frac{9L}{\gcd(8,L)})=1 gcd(10,gcd(8,L)9L)=1
Otherwise, convert to a x ≡ 1 ( m o d m ) a^x\equiv 1\pmod m ax ≡ 1(modm), find the minimum x x x
According to the formula of order x ∣ ϕ ( m ) x\bigg|\phi(m) x∣∣∣∣ϕ(m)
Direct enumeration calculation
code
#include <cstdio> #include <cstring> #include <iostream> using namespace std; #define int long long int gcd( int x, int y ) { if( ! y ) return x; else return gcd( y, x % y ); } int calc( int x ) { int ans = x; for( int i = 2;i * i <= x;i ++ ) if( x % i == 0 ) { ans = ans / i * ( i - 1 ); while( x % i == 0 ) x /= i; } if( x != 1 ) ans = ans / x * ( x - 1 ); return ans; } int qkmul( int x, int y, int mod ) { int ans = 0; while( y ) { if( y & 1 ) ans = ( ans + x ) % mod; x = ( x + x ) % mod; y >>= 1; } return ans; } int qkpow( int x, int y, int mod ) { int ans = 1; while( y ) { if( y & 1 ) ans = qkmul( ans, x, mod ); x = qkmul( x, x, mod ); y >>= 1; } return ans; } signed main() { int L; for( int T = 1;;T ++ ) { scanf( "%lld", &L ); if( ! L ) return 0; L *= 9; for( int i = 1;i <= 3;i ++ ) if( L % 2 == 0 ) L >>= 1; else break; if( gcd( 10, L ) != 1 ) { printf( "Case %lld: 0\n", T ); continue; } int phi = calc( L ), ans = L; for( int i = 1;i * i <= phi;i ++ ) if( phi % i ) continue; else { if( qkpow( 10, i, L ) == 1 ) { ans = i; break; } else if( qkpow( 10, phi / i, L ) == 1 ) ans = min( ans, phi / i ); } printf( "Case %lld: %lld\n", T, ans ); } return 0; }
CF906D Power Tower
description
solution
Board problems of extended Euler theorem
x
r
≡
{
x
r
r
<
m
x
r
%
ϕ
(
m
)
(
x
,
m
)
=
1
x
r
%
ϕ
(
m
)
+
ϕ
(
m
)
(
x
,
m
)
>
1
x^r\equiv \begin{cases} x^r&&r<m\\ x^{r\%\phi(m)}&&(x,m)=1\\ x^{r\%\phi(m)+\phi(m)}&&(x,m)>1 \end{cases}
xr≡⎩⎪⎨⎪⎧xrxr%ϕ(m)xr%ϕ(m)+ϕ(m)r<m(x,m)=1(x,m)>1
Iterative calculation index, current layer
m
o
d
mod
mod
ϕ
(
m
o
d
)
\phi(mod)
ϕ (mod) is the next level of its index
m
o
d
′
mod'
mod′
code
#include <iostream> #include <cstdio> using namespace std; #if(__cplusplus == 201103L) #include <unordered_map> #else #include <tr1/unordered_map> namespace std { using std::tr1::unordered_map; } #endif #define int long long #define maxn 100005 unordered_map < int, int > mp; int l, r; int w[maxn]; int E( int x, int mod ) { return x < mod ? x : x % mod + mod; } int qkpow( int x, int y, int mod ) { int ans = 1; while( y ) { if( y & 1 ) ans = E( ans * x, mod ); x = E( x * x, mod ); y >>= 1; } return ans; } int phi( int n ) { if( mp.count( n ) ) return mp[n]; int ans = n, x = n; for( int i = 2;i * i <= x;i ++ ) if( x % i == 0 ) { ans = ans / i * ( i - 1 ); while( x % i == 0 ) x /= i; } if( x != 1 ) ans = ans / x * ( x - 1 ); return mp[n] = ans; } int solve( int d, int pos, int mod ) { if( pos == r + 1 || mod == 1 ) return E( d, mod ); int p = phi( mod ); int e = solve( w[pos], pos + 1, p ); return qkpow( d, E( e, p ), mod ); } signed main() { int n, mod, Q; scanf( "%lld %lld", &n, &mod ); for( int i = 1;i <= n;i ++ ) scanf( "%lld", &w[i] ); scanf( "%lld", &Q ); while( Q -- ) { scanf( "%lld %lld", &l, &r ); printf( "%lld\n", solve( w[l], l + 1, mod ) % mod ); } }
Minimal Power of Prime
description
solution
An integer standard unique decomposition problem with a large data range
Trial division method
Use no more than n 1 5 n^\frac{1}{5} Prime number removal to the power of n51 n n n. So n n n up to four prime factors remain
Conditional statements are discussed vigorously, n n If n is not a second power / third power / fourth power, it must belong to the case that at least one is a first power
code
#include <iostream> #include <cstdio> #include <cmath> using namespace std; #define maxn 1000000 #define int long long int T, n, cnt; bool vis[maxn]; int prime[maxn]; void sieve() { for( int i = 2;i < maxn;i ++ ) { if( ! vis[i] ) vis[i] = 1, prime[++ cnt] = i; for( int j = 1;j <= cnt && i * prime[j] < maxn;j ++ ) { vis[i * prime[j]] = 1; if( i % prime[j] == 0 ) break; } } } int calc( int x, int t ) { int ans = 1; for( int i = 1;i <= t;i ++ ) ans *= x; return ans; } signed main() { sieve(); scanf( "%lld", &T ); while( T -- ) { scanf( "%lld", &n ); int m = powl( n, 1.0 / 5 ), ans = n; for( int i = 1;i <= cnt;i ++ ) if( prime[i] > m ) break; else if( n % prime[i] == 0 ) { int tot = 0; while( n % prime[i] == 0 ) tot ++, n /= prime[i]; ans = min( ans, tot ); } int x = powl( n, 1.0 / 4 ); int y = powl( n, 1.0 / 3 ); int z = powl( n, 1.0 / 2 ); if( n == 1 ) goto print; if( calc( x, 4 ) == n || calc( x - 1, 4 ) == n || calc( x + 1, 4 ) == n ) ans = min( ans, 4ll ); else if( calc( y, 3 ) == n || calc( y - 1, 3 ) == n || calc( y + 1, 3 ) == n ) ans = min( ans, 3ll ); else if( calc( z, 2 ) == n || calc( z - 1, 2 ) == n || calc( z + 1, 2 ) == n ) ans = min( ans, 2ll ); else ans = min( ans, 1ll ); print : printf( "%lld\n", ans ); } return 0; }
[SDOI2008] guard of honor
description
solution
Define the coordinates of each point as ( x − 1 , y − 1 ) (x-1,y-1) (x − 1,y − 1), then C C C Jun is right there ( 0 , 0 ) (0,0) (0,0) position
Consider the properties of the point coordinates of the children that can be seen
According to the fact that a line can be characterized by a vector, let ( x , y ) (x,y) (x,y) if the child can be seen, then the child on this straight line λ > 1 , ( λ x , λ y ) \lambda>1,(\lambda x,\lambda y) λ> 1,( λ x, λ y) Will be blocked
And gcd ( λ x , λ y ) = λ ( x , y ) ≥ λ > 1 \gcd(\lambda x,\lambda y)=\lambda(x,y)\ge \lambda>1 gcd(λx,λy)=λ(x,y)≥λ>1
That is, if gcd ( x , y ) > 1 \gcd(x,y)>1 GCD (x, y) > 1 the child will be blocked
If gcd ( x , y ) = 1 \gcd(x,y)=1 Children with gcd(x,y)=1 will be blocked, then they must exist ( x μ , y μ ) , μ > 1 (\frac{x}{\mu},\frac{y}{\mu}),\mu>1 ( μ x, μ y), μ> 1 children exist, obviously there is no such point
To sum up, it can be seen only when the children's abscissa and ordinate are coprime
Translated into mathematical language, i.e.: a n s = ∑ i = 0 n − 1 ∑ j = 0 n − 1 [ gcd ( i , j ) = 1 ] ans=\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}\Big[\gcd(i,j)=1\Big] ans=∑i=0n−1∑j=0n−1[gcd(i,j)=1]
⇔ ∑ i = 0 n − 1 ∑ j = 0 i − 1 [ gcd ( i , j ) = 1 ] + ∑ i = 0 n − 1 ∑ j = i i [ gcd ( i , j ) = 1 ] + ∑ i = 0 n − 1 ∑ j = i + 1 n − 1 [ gcd ( i , j ) = 1 ] \Leftrightarrow \sum_{i=0}^{n-1}\sum_{j=0}^{i-1}\Big[\gcd(i,j)=1\Big]+\sum_{i=0}^{n-1}\sum_{j=i}^i\Big[\gcd(i,j)=1\Big]+\sum_{i=0}^{n-1}\sum_{j=i+1}^{n-1}\Big[\gcd(i,j)=1\Big] ⇔∑i=0n−1∑j=0i−1[gcd(i,j)=1]+∑i=0n−1∑j=ii[gcd(i,j)=1]+∑i=0n−1∑j=i+1n−1[gcd(i,j)=1]
∑ i = 0 n − 1 ∑ j = i i [ gcd ( i , j ) = 1 ] \sum_{i=0}^{n-1}\sum_{j=i}^i\Big[\gcd(i,j)=1\Big] Σ i=0n − 1 Σ j=ii [gcd(i,j)=1] represents y = x y=x y=x straight line, obviously only one child can be seen, and then it can be deleted
n × n n\times n n × Graph of N, C C C Jun is at the origin. The hidden nature is what the children see about y = x y=x y=x linear symmetry
The formula continues to be 2 ( ∑ i = 0 n − 1 ∑ j = 0 i − 1 [ gcd ( i , j ) = 1 ] ) 2\bigg(\sum_{i=0}^{n-1}\sum_{j=0}^{i-1}\Big[\gcd(i,j)=1\Big]\bigg) 2(∑i=0n−1∑j=0i−1[gcd(i,j)=1])
Surprisingly, it is found that the value range and requirements of the inner loop fully comply with the Euler function φ \varphi φ Definition of
So the final answer is 1 + 2 ∑ i = 0 n − 1 φ ( i ) 1+2\sum_{i=0}^{n-1}\varphi(i) 1+2∑i=0n−1φ(i)
code
#include <cstdio> #define maxn 40005 int prime[maxn], phi[maxn]; bool vis[maxn]; int n; void sieve() { phi[1] = 1; int cnt = 0; for( int i = 2;i <= n;i ++ ) { if( ! vis[i] ) prime[++ cnt] = i, phi[i] = i - 1; for( int j = 1;j <= cnt && i * prime[j] <= n;j ++ ) { vis[i * prime[j]] = 1; if( i % prime[j] == 0 ) { phi[i * prime[j]] = phi[i] * prime[j]; break; } else phi[i * prime[j]] = phi[i] * ( prime[j] - 1 ); } } } int main() { scanf( "%d", &n ); if( n == 1 ) return ! printf( "0\n" ); sieve(); int ans = 0; for( int i = 0;i < n;i ++ ) ans += ( phi[i] << 1 ); printf( "%d\n", ans + 1 ); }
LCMSUM
description
solution
∑ i = 1 n lcm ( i , j ) ⇔ ∑ i = 1 n i × n gcd ( i , n ) \sum_{i=1}^n \operatorname{lcm}(i,j)\Leftrightarrow \sum_{i=1}^n\frac{i\times n}{\operatorname{gcd}(i,n)} ∑i=1nlcm(i,j)⇔∑i=1ngcd(i,n)i×n
∵ gcd ( i , n ) = gcd ( n − i , n ) \because \gcd(i,n)=\gcd(n-i,n) ∵ gcd(i,n)=gcd(n − i,n), two by two gcd \gcd gcd same merge i + ( n − i ) = n i+(n-i)=n i+(n−i)=n
1 2 ( ∑ i = 1 n − 1 i ∗ n gcd ( i , n ) + ∑ i = n − 1 1 i ∗ n gcd ( i , n ) ) + lcm ( n , n ) = n + 1 2 ∑ i = 1 n − 1 n 2 gcd ( i , j ) \frac{1}{2}\Big(\sum_{i=1}^{n-1}\frac{i*n}{\gcd(i,n)}+\sum_{i=n-1}^1\frac{i*n}{\gcd(i,n)}\Big)+\operatorname{lcm}(n,n)=n+\frac{1}{2}\sum_{i=1}^{n-1}\frac{n^2}{\gcd(i,j)} 21(∑i=1n−1gcd(i,n)i∗n+∑i=n−11gcd(i,n)i∗n)+lcm(n,n)=n+21∑i=1n−1gcd(i,j)n2
gcd ( i , n ) = d \gcd(i,n)=d gcd(i,n)=d i i The number of i is ϕ ( n d ) \phi(\frac{n}{d}) ϕ (dn) Nos ( g c d ( i d , n d ) = 1 \Big(gcd(\frac{i}{d},\frac{n}{d})=1 (the number of gcd(di, dn) = 1 is ϕ ( n d ) ) \phi(\frac{n}{d})\Big) ϕ(dn))
⇒ n + 1 2 ∑ i = 1 n − 1 n 2 gcd ( i , j ) = n + 1 2 ∑ d ∣ n n 2 ⋅ ϕ ( n d ) d = n + 1 2 ∑ d ∣ n n 2 ⋅ ϕ ( d ) n d \Rightarrow n+\frac{1}{2}\sum_{i=1}^{n-1}\frac{n^2}{\gcd(i,j)}=n+\frac{1}{2}\sum_{d\big|n}\frac{n^2·\phi(\frac{n}{d})}{d}=n+\frac{1}{2}\sum_{d\big|n}n^2·\frac{\phi(d)}{\frac{n}{d}} ⇒n+21∑i=1n−1gcd(i,j)n2=n+21∑d∣∣ndn2⋅ϕ(dn)=n+21∑d∣∣nn2⋅dnϕ(d)
= n + n ∑ d ∣ n d ⋅ ϕ ( d ) 2 =n+n\sum_{d\big|n}\frac{d·\phi(d)}{2} =n+n∑d∣∣n2d⋅ϕ(d)
Linear sieve pretreatment
code
#include <cstdio> #define maxn 1000000 #define int long long int prime[maxn + 5], phi[maxn + 5], sum[maxn + 5]; bool vis[maxn + 5]; void sieve() { phi[1] = 1; int cnt = 0; for( int i = 2;i <= maxn;i ++ ) { if( ! vis[i] ) prime[++ cnt] = i, phi[i] = i - 1; for( int j = 1;j <= cnt && i * prime[j] <= maxn;j ++ ) { vis[i * prime[j]] = 1; if( i % prime[j] == 0 ) { phi[i * prime[j]] = phi[i] * prime[j]; break; } else phi[i * prime[j]] = phi[i] * ( prime[j] - 1 ); } } for( int i = 1;i <= maxn;i ++ ) for( int j = 1;i * j <= maxn;j ++ ) sum[i * j] += i * phi[i] / 2; for( int i = 1;i <= maxn;i ++ ) sum[i] = sum[i] * i + i; } signed main() { sieve(); int T, n; scanf( "%lld", &T ); while( T -- ) { scanf( "%lld", &n ); if( n == 1 ) printf( "1\n" ); else printf( "%lld\n", sum[n] ); } return 0; }