ARC113 题解
比赛地址
A. A * B * C
枚举 \(A,B\) , 直接计算可能的 \(C\) 的个数。
复杂度和调和级数相同,为 \(\mathcal O(n \ln n)\)
B. A ^ B ^ C
直接扩展欧拉定理计算即可。
C. String Invasion
倒着扫字符串,遇到连续两个相同字符计算答案。
细节有点多, WA 了很多次。
D. Sky Reflector
可以发现,合法的 \((A,B)\) 一定满足 \(\max A \le \min B\),我们统计后者数量即可。
首先枚举 \(\max A\) 的值 , 记为 \(p\) ,分别计算合法的 \(A\) , \(B\) 数量
- A 枚举最小值的数量和位置,剩下的随便选小于 \(p\) 的数,有
\[\begin{aligned}
&\sum_{i=1}^n \binom{n}{i} (p-1)^{n-i} \\
=&\sum_{i=0}^n \binom{n}{i} (p-1)^{n-i} - (p-1)^i \\
=&p^n - (p-1)^n \\
\end{aligned}\]
- B 随便选不小于 \(p\) 的数,有
\[(k-p+1)^m
\]
注意到 \(n=1\) 或 \(m=1\) 时需要特殊处理。
复杂度 \(\mathcal O(k \log n)\) , 当然你可以线筛 \(n/m\) 次幂做到线性复杂度。
#include <cstdio>
const int MAXN = 2e5 , Mod = 998244353;
int Add( int x , int y ) { x += y; return x >= Mod ? x - Mod : x; }
int Sub( int x , int y ) { x -= y; return x < 0 ? x + Mod : x; }
int Mul( int x , int y ) { return 1ll * x * y % Mod; }
int Qkpow( int x , int po ) { int p = 1; for( ; po ; po >>= 1 , x = Mul( x , x ) ) if( po & 1 ) p = Mul( p , x ); return p; }
int n , m , k;
int main( ) {
scanf("%d %d %d",&n,&m,&k);
int Ans = 0;
for( int i = 1 ; i <= k ; i ++ ) {
if( n == 1 || m == 1 ) Ans = Add( Ans , Mul( Sub( Qkpow( i , n ) , Qkpow( i - 1 , n ) ) , Sub( Qkpow( k - i + 1 , m ) , Qkpow( k - i , m ) ) ) );
else Ans = Add( Ans , Mul( Sub( Qkpow( i , n ) , Qkpow( i - 1 , n ) ) , Qkpow( k - i + 1 , m ) ) );
}
printf("%d\n", Ans );
return 0;
}