牛客练习赛64 C 序列卷积之和 (推式子 数学)

题目:传送门

题意

 

 

 

 

 思路

官方题解: 地址

 

 

#include <bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define UI unsigned int
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF 0x3f3f3f3f
#define inf LLONG_MAX
#define PI acos(-1)
#define fir first
#define sec second
#define lb(x) ((x) & (-(x)))
#define dbg(x) cout<<#x<<" = "<<x<<endl;
using namespace std;

const int N = 1e6 + 5;

const LL mod = 1e9 + 7;

LL ksm(LL a, LL b) {

    LL res = 1LL;

    while(b) {

        if(b & 1) res = res * a % mod;

        a = a * a % mod;

        b >>= 1;

    }

    return res;

}

LL s[N], a[N];

void solve() {
    
    /// 最终答案是l:1~n; r:l~n ( 1/2 * (a[l] + a[l+1] + ... + a[r] )^2 + 1/2 * (a[l]^2 + a[l + 1]^2 + ..... + a[r]^2 ) )
    /// 其中 (a[l] + a[l+1] + ... + a[r] )^2 = (a[l]^2 + a[l + 1]^2 + ..... + a[r]^2 ) + (2*a[l]*a[l+1] + ... + 2*a[l]*a[r] + ... 2*a[l+1]*a[l+2] + ... 2*a[l+1]*a[r] +....)
    /// 最终就是 (a[l]*a[l+1] + ... + a[l]*a[r] + ... a[l+1]*a[l+2] + ... a[l+1]*a[r] +....) + (a[l]^2 + a[l + 1]^2 + ..... + a[r]^2 )
    /// 对于 l <= i 和 r >= j,都会算一次 a[i]*a[j],那么直接预处理。
    
    int n;

    scanf("%d", &n);

    rep(i, 1, n) scanf("%lld", &a[i]);

    rep(i, 1, n) s[i] = (s[i - 1] + 1LL * (n - i + 1) * a[i] % mod) % mod;

    LL ans = 0LL;

    rep(i, 1, n) { 
        
        ans = (ans + 1LL * i * a[i] % mod * (s[n] - s[i - 1]) % mod + mod) % mod;

    }

    printf("%lld\n", ans);

}


int main() {

//    int _; scanf("%d", &_);
//    while(_--) solve();

    solve();

    return 0;
}

 

posted on 2020-05-25 23:15  Willems  阅读(191)  评论(0编辑  收藏  举报

导航