牛客小白月赛118

C-绿_牛客小白月赛118

明确:一个大小为n的序列,子序列和为:

本题中,恰好只需要计算这个值,-1因为这包括了空序列

如何快速计算2^ L 呢?

想到快速幂算法:

base是基数,这里是2,exponent是轮数,

cpp 复制代码
long long fast_pow(long long base, long long exponent, long long mod) {
    long long res = 1;
    base %= mod;  // 防止base过大
    while (exponent) {
        // 如果当前指数为奇数,乘以当前底数
        if (exponent & 1) {
            res = (res * base) % mod;
        }
        // 底数平方
        base = (base * base) % mod;
        // 指数右移一位
        exponent /= 2;  // 或 exponent >>= 1;
    }
    return res;
}

再进一步如何快速化简呢?

求2^e%(p-1) , 再%p是我们的目标

所以,来看代码

cpp 复制代码
#include <iostream>
#include <string>
#include <vector>
using namespace std;

const long long MOD = 1000000007;
const long long mod_phi = MOD - 1;  // φ(MOD) for MOD prime

long long fast_pow(long long base, long long exponent, long long mod) {
    long long res = 1;
    base %= mod;
    while (exponent) {
        if (exponent & 1) {
            res = (res * base) % mod;
        }
        base = (base * base) % mod;
        exponent /= 2;
    }
    return res;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;
    while (T--) {
        long long n;
        cin >> n;
        string s;
        cin >> s;
        long long len = s.size();

        long long n1 = n % mod_phi;
        long long exponent_mod = (n1 * len) % mod_phi;

        long long power = fast_pow(2, exponent_mod, MOD);
        long long ans = (power - 1) % MOD;
        if (ans < 0) {
            ans += MOD;
        }
        cout << ans << '\n';
    }

    return 0;
}