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;
}

E.

F.

posted @ 2021-04-15 20:25  chihik  阅读(161)  评论(0编辑  收藏  举报