牛客周赛 Round 79 题解(A-F)

2025/02/26 另一篇博客里提到的错误已纠正

A.小红的合数寻找

我们知道除了 以外的偶数均为质数,因此 一定为合数。

时显然无解

x = int(input())
print(2*x if x!=1 else -1)

B.小红的小球染色

不难想到,我们无间隔的选择白色小球,此时为最大值。

由于如果有两个连续的不会结束,因此我们选择的一定只能间隔一个。

时,间隔一个选择后会剩下一组白色小球,仍会被选择。

n = int(input())
print(n//3 + (n%3 == 2), n//2)

C.小红的二叉树

简称长度为 的简单路径为 路径

对每个节点,若其下方至少有两层,则以该节点为起点的 路径有 条。(图一)

同时,若该节点不为叶子结点,则有一条从左节点经过该节点到到右节点的 路径。(图二)

C1 C2

n = int(input())
ans = 0
pre = 1
for i in range(1, n):
    if n - i >= 2:
        ans =(ans + 4 * pre)%(10**9+7)
    ans = (ans + pre)%(10**9+7)
    pre = (pre * 2)%(10**9+7)# 每一层节点数翻倍
print(ans%(10**9+7))

D.小红的“质数”寻找

开头为 ,则 (长度和 相同) 一定在 区间内。

开头为 ,则 (长度和 相同) 一定在 区间内。

开头为 ,则 (长度和 相同) 一定在 区间内。

开头大于等于 ,则 (长度比 大一位) 一定在 区间内。

开头为 ,当 时,本身满足条件;当 不为 时,则 (长度比 大一位) 一定在 区间内。

t = int(input())
for _ in range(t):
    x = input()
    if  int(x[0]) > 5:
        print('11' + '0'*(len(x)-1))
    elif int(x[0]) == 5:
        if x == '5':
            print('5')
        elif x[0] == '5' and all([i=='0' for i in x[1:]]):
            print(x)
        else:
            print('1'+'0'*(len(x)-1) + '1')
    elif int(x[0]) == 4:
        print('5' + '0'*(len(x)-1))
    elif int(x[0]) == 3:
        print('5' + '0'*(len(x)-1))
    elif int(x[0]) == 2:
        print('3' + '0'*(len(x)-1))
    elif int(x[0]) == 1:
        print('2' + '0'*(len(x)-1))

E.小红的好排列

时, 的倍数

, 则一定不可能有一半的满足。

, 则一定有 满足 ,此时有 中方法(有 中排列 的方式,再有 种 选择 的方式。

剩下的 个满足 ,需放在 的 地方,有 种排列方式。

其余的 随便排列,有 种方法。

答案为

#include <bits/stdc++.h>
using namespace std;
  
typedef long long ll;
typedef pair<long long,long long> PLL;
typedef tuple<ll,ll,ll> TLLL;
const ll inf =  0x3f3f3f3f;
const ll INF = INT_MAX;
  
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
   
inline void pt(ll x){if(x<0) putchar('-'),x=-x;if(x>9) pt(x/10);putchar(x%10+'0');}
   
void print(ll x){pt(x), puts("");}


const ll mod = 1e9+7;
ll fac[1000009];
ll ifac[1000009];
ll ksm(ll a,ll b){
    ll ans = 1;
    while(b){
        if(b&1)ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}
ll C(ll a,ll b){
    return fac[a] * ifac[b] % mod * ifac[a-b] % mod;
}

ll A(ll n, ll m){
    return fac[n] * ifac[n-m] % mod;
}

void solve(){
    ll n = read();
    ll k = n/3;
    if (k * 2 < n/2 ){
        print(0);
    }
    else{
        ll m = k * 2 - n/2;
        ll use = k - m;
        ll t1 = (A(k, m) *  C(k, m) % mod );
        ll ans = (t1 * A(n - k, use) %mod )* A(n-k, n-k)%mod;
        print(ans);
    }
    
}

int main(){
    fac[0] = ifac[0] = 1;
    for(int i = 1; i <= 1000002; i++){
        fac[i] = fac[i-1] * i % mod;
    }
    ifac[1000002] = ksm(fac[1000002], mod-2);
    for(int i = 1000002-1; i >= 1; i--){
        ifac[i] = ifac[i+1] * (i+1) % mod;
    }
    ll t = 1;
    //t = read();
    while(t--){
        solve();
    }
}

F.小红的小球染色期望

时的期望。

易得,

考虑其他情况时,我们考虑选择的左端点,有 中选择,每种选择的概率为

每种选择后,会剩下左右两段,每段结束的期望在 较小的计算中可以得出。

观察发现左端的长度会从 取到 , 右端从 取到 ,期望总和为(这可以用前缀和优化)。

加上这一次操作有

#include <bits/stdc++.h>
using namespace std;
  
typedef long long ll;
typedef pair<long long,long long> PLL;
typedef tuple<ll,ll,ll> TLLL;
const ll inf =  0x3f3f3f3f;
const ll INF = INT_MAX;
  
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
   
inline void pt(ll x){if(x<0) putchar('-'),x=-x;if(x>9) pt(x/10);putchar(x%10+'0');}
   
void print(ll x){pt(x), puts("");}


const ll mod = 1e9+7;

ll ksm(ll a,ll b){
    ll ans = 1;
    while(b){
        if(b&1)ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}

ll dp[1000009];
ll pre[1000009];
int main(){
    ll n = read();
    dp[2] = 1;
    pre[2] = 1;
    for(ll i=3;i<=n;i++){
        ll p = ksm(i-1, mod-2);
        dp[i] = (dp[i] + pre[i-2]*2%mod*p%mod)%mod;
        dp[i] = (dp[i] + 1)%mod;
        pre[i] = (pre[i-1] + dp[i])%mod;
    }
    print(dp[n]);
    
}