P14967 『LHB-OI』Round 1 B题 Watching the Moon

题意

题目内容

给定长度为 \(n\),的序列 \(a\)

\[\sum_{k=1}^{n} \left\{ a_k + \sum_{i=1}^{k-1}\sum_{j=1}^{k-1} \Biggl[ \Biggl( \prod_{l=1}^{i} a_{l}^{\,2^{\,i-l}} \Biggr) \Biggl( \prod_{l=1}^{j} a_{l}^{\,2^{\,j-l}} \Biggr) \Biggr] \right\} \]

\(10^9+7\) 取模后的结果。

数据范围与提示

\(n\le 5\times 10^6\)\(a_i\le 10^9\)

时间限制 \(300ms\), 空间限制 \(5MB\)

解决

尝试缩减式子,

优化其中的 :

\[\Biggl( \prod_{l=1}^{i} a_{l}^{\,2^{\,i-l}} \Biggr) 和 \Biggl( \prod_{l=1}^{j} a_{l}^{\,2^{\,j-l}} \Biggr)\]

尝试第推处理。

首先我们定义:

\[f(x)=\prod_{l=1}^{x}a_l^{2^{x-l}} \]

我们尝试预处理每个 \(f(i)\)

\[f(x+1)=\prod_{l=1}^{x}a_l^{2^{x-l+1}} * a_{x+1}=\prod_{l=1}^{x}a_l^{2^{x-l}*2} * a_{x+1}=f(x)^2 * a_{x+1} \]

得结论:

\[f(x+1)=f(x)^2*a_{x+1} \]

\[f(x)=f(x-1)^2*a_x \]

接下来我们要求:

\[\sum_{k=1}^{n} \left\{ a_k + \sum_{i=1}^{k-1}\sum_{j=1}^{k-1} \Biggl[ \Biggl( \prod_{l=1}^{i} a_{l}^{\,2^{\,i-l}} \Biggr) \Biggl( \prod_{l=1}^{j} a_{l}^{\,2^{\,j-l}} \Biggr) \Biggr] \right\} \]

推导:

\[\sum_{k=1}^{n} \left\{ a_k + \sum_{i=1}^{k-1}\sum_{j=1}^{k-1} \Biggl[ \Biggl( \prod_{l=1}^{i} a_{l}^{\,2^{\,i-l}} \Biggr) \Biggl( \prod_{l=1}^{j} a_{l}^{\,2^{\,j-l}} \Biggr) \Biggr] \right\} \]

\[=\sum_{k=1}^{n} \left\{ a_k + \sum_{i=1}^{k-1}\sum_{j=1}^{k-1} \Biggl[ f(i) f(j) \Biggr] \right\} \]

\[=\sum_{k=1}^{n} \left\{ a_k + \Biggr[ \sum_{i=1}^{k-1}f(i)*\sum_{j=1}^{k-1}f(j)\Biggr] \right\} \]

\[=\sum_{k=1}^{n} \left\{ a_k + \Biggr( \sum_{i=1}^{k-1}f(i)\Biggr)^2 \right\} \]

\[=\sum_{k=1}^{n} a_k + \sum_{k=1}^{n}\Biggr[\Biggr( \sum_{i=1}^{k-1}f(i)\Biggr)^2\Biggr] \]

\[\sum_{k=1}^{n} \left\{ a_k + \sum_{i=1}^{k-1}\sum_{j=1}^{k-1} \Biggl[ \Biggl( \prod_{l=1}^{i} a_{l}^{\,2^{\,i-l}} \Biggr) \Biggl( \prod_{l=1}^{j} a_{l}^{\,2^{\,j-l}} \Biggr) \Biggr] \right\}=\sum_{k=1}^{n} a_k + \sum_{k=1}^{n}\Biggr[\Biggr( \sum_{i=1}^{k-1}f(i)\Biggr)^2\Biggr] \]

根据化后的公式编码。

分别建立变量用于第推函数 \(f\),记录\(f\)的和,及答案求和变量。

本题时限较短。注意常数优化。

#include <bits/stdc++.h>

typedef unsigned  long long ll;

const ll mod=1e9+7;

using std::cin;
using std::cout;


template< typename Type >
inline Type fread(Type* p) {
    Type ret = 0, sgn = 0, ch = getchar();
    while (!isdigit(ch)) {
        sgn |= ch == '-', ch = getchar();
    }
    while (isdigit(ch)) ret = ret * 10 + ch - '0', ch = getchar();
    if (p != nullptr) {
        *p = Type(sgn ? -ret : ret);
    }
    return sgn ? -ret : ret;
}

ll n,sum=0,f=1,temp,ans=0;

int main() {
    //freopen("input","r",stdin);

    //cin>>n;
    //scanf("%llu",&n);
    fread(&n);
    for(ll i=1;i<=n;++i) {
        ll val=0;
    //    scanf("%llu",&val);
        fread(&val);
        f=f%mod*f%mod*val%mod;
        f%=mod;
        ans+=temp%mod*temp%mod;
        ans%=mod;
        ans+=val;
        ans%=mod;
        temp+=f;
        temp%=mod;
    }

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


    return 0;
}

posted @ 2026-01-18 12:28  txp2025  阅读(4)  评论(0)    收藏  举报