首页 > 其他分享 >LG10185

LG10185

时间:2024-03-20 21:23:40浏览次数:13  
标签:qp int sum LG10185 times 式子 MOD

读完题目后,发现如果暴力枚举每种方案,时间复杂度非常高,似乎不是很可行。

注意到要求的是美丽值总和,也就是并不关心具体的方案,所以可以考虑分别求出每颗珠子的贡献。又因为同种颜色珠子的个数对贡献有影响,因此不妨对每种颜色的珠子分别计算,再累加即可。以上为大致思路。

具体地,对于第 \(i\) 种颜色,暴力枚举珠子数并计算对应的组合数,再计算出单次贡献和剩余的珠子选取的方案数(每颗都可选可不选),将它们乘起来,得到如下式子,式子的值即为第 \(i\) 种颜色的贡献(\(a_i\) 和 \(v_i\) 的含义如题):

\[\sum_{j=1}^{a_i}2^{n-a_i} \times C_{a_i}^{j} \times v_i^{j} \]

总答案式子也不难得到:

\[\sum_{i=1}^n\sum_{j=1}^{a_i}2^{n-a_i} \times C_{a_i}^{j} \times v_i^{j} \]

直接暴力计算,时间复杂度 \(O(n^2)\),可以获得 \(40\) 分。这里就不给出代码了。

考虑如何优化上述计算过程。发现 \(2^{n-a_i}\) 这一项对于每一个固定的 \(i\) 是不变的,因此可以在最后再乘上。对于剩下的部分,我们发现它与二项式的展开式非常相似,因此可以尝试配成二项式。

注意到 \(1\) 的任意正整数次方都为 \(1\),因此原式可以等价为

\[\sum_{j=1}^{a_i} C_{a_i}^{j} \times v_i^{j} \times 1^{a_i-j} \]

这样就能化成 \((v_i + 1)^{a_i}\)。当然,该式子多算上了 \(j=0\) 的情况,此时的值为 \(1\),所以要在上述式子的基础上减 \(1\) 才是正确的。

总结上面的推导,可以得到以下计算总答案的式子:

\[\sum_{i=1}^n 2^{n - a_i} \times [(v_i+1)^{a_i}-1] \]

使用快速幂计算即可,时间复杂度 \(O(n \log n)\)。

完整代码如下:

#include <iostream>
#include <cstdio>
#define int long long
#define MOD 1000000007

using namespace std;

int n,a[1000001],b[1000001],ans,sum = 1;

int qp( int a , int b )
{
    int c = 1;
    while( b )
    {
        if( b & 1 ) c = c * a % MOD;
        b >>= 1;
        a = a * a % MOD;
    }
    return c;
}

signed main()
{
    cin >> n;
    for( int i = 1 ; i <= n ; i ++ )
        cin >> a[i],sum = sum * qp( 2 , a[i] ) % MOD;
    for( int i = 1 ; i <= n ; i ++ )
    {
        cin >> b[i];
        sum = sum * qp( qp( 2 , a[i] ) , MOD - 2 ) % MOD;
        ans = ( ans + sum * ( qp( b[i] + 1 , a[i] ) - 1 + MOD ) % MOD ) % MOD;
        sum = sum * qp( 2 , a[i] ) % MOD; 
    }
    cout << ans;
    return 0;
}

标签:qp,int,sum,LG10185,times,式子,MOD
From: https://www.cnblogs.com/-lilong-/p/18086121

相关文章