列表

详情


NC50566. 柳下惠的数学题

描述

定义一个无限长的数组,给定前n项,若i>n,则a[i]=a[i-n]。接下来有Q次询问,每次给定一个N,你只需回答对1e9+7取模的结果。

输入描述

第一行输入n,Q 第二行输入n个数字表示a数组的前n项 接下来Q行,每行输入一个N表示一次询问。 1<=a[i],n<=3000000,1<=Q<=300000,1<=N<=1e18

输出描述

每次询问,输出一个整数。

示例1

输入:

3 3
1 2 3
4
10
15

输出:

186
4780
21820

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 483ms, 内存消耗: 73836K, 提交时间: 2019-10-12 17:17:10

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3000010;
const int mod=1e9+7;
const int inv2=500000004;
const int inv6=166666668;
ll s[maxn],ps1[maxn],ps2[maxn],N,n,q;
inline void Add(ll &x,const ll y)
{
    x+=y;
    if(x>=mod) x-=mod;
}
inline ll f(ll n)
{
    return n*(n+1)%mod*(2*n+1)%mod*inv6%mod;
}
inline ll solve()
{
    ll m=N/n%mod,k=N%n,ans=0,sum=0;
    ans=(m*ps2[n]%mod+f((m-1+mod)%mod)*n%mod*s[n]%mod*s[n]%mod+(m-1+mod)%mod*m%mod*s[n]%mod*ps1[n]%mod)%mod;
    sum=(m*ps1[n]%mod+(m-1+mod)%mod*m%mod*n%mod*inv2%mod*s[n]%mod)%mod;
    if(k){
        Add(ans,(ps2[k]+k*m%mod*m%mod*s[n]%mod*s[n]%mod+2*m%mod*s[n]%mod*ps1[k]%mod)%mod);
        Add(sum,(ps1[k]+k*m%mod*s[n]%mod)%mod);
    }
    ans=(N+1)%mod*ans%mod;
    Add(ans,(mod-sum*sum%mod)%mod);
    return ans;
}
inline ll read()
{
    char ch=getchar();
    if(ch==EOF) return 0;
    ll ans=0;
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    return ans;
}
int main()
{
    #ifdef local
    freopen("a.in","r",stdin);
    #endif // local
    n=read(),q=read();
    for(int i=1;i<=n;++i){
        Add(s[i]=s[i-1],read());
        Add(ps1[i]=ps1[i-1],s[i]);
        Add(ps2[i]=ps2[i-1],s[i]*s[i]%mod);
    }
    while(q--){
        N=read();
        printf("%lld\n",solve());
    }
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 1282ms, 内存消耗: 38520K, 提交时间: 2019-10-11 20:15:52

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define P 1000000007
#define MAXN 3000005
int n,q,s,i,t,a[MAXN],x[MAXN],y[MAXN],ans;
ll m,m1,m2;
int main()
{
    scanf("%d%d",&n,&q);
    for(i=1;i<=n;i++)
    {
        scanf("%d",a+i);
        a[i]+=a[i-1];
        if(a[i]>=P)a[i]-=P;
    }
    t=a[n];
    for(i=1;i<n;i++)
    {
        x[i]=x[i-1]+a[i];
        if(x[i]>=P)x[i]-=P;
        y[i]=(y[i-1]+(ll)a[i]*a[i])%P;
    }
    while(q--)
    {
        scanf("%lld",&m);
        s=m%n;
        m2=(m+1)%P;
        m=m/n%P;
        m1=m-1;
        if(m1<0)m1+=P;
        ans=((m+1)*y[s]+t*m%P*(m+1)%P*x[s]+(ll)t*t%P*m%P*(m+1)%P*(2*m+1)%P*(P+1)/6%P*(s+1)+(m1+1)*(y[n-1]-y[s]+P)+t*m1%P*(m1+1)%P*(x[n-1]-x[s]+P)+(ll)t*t%P*m1%P*(m1+1)%P*(2*m1+1)%P*(P+1)/6%P*(n-s-1))%P*m2%P;
        i=((m+1)*x[s]+t*m%P*(m+1)%P*(P+1>>1)%P*(s+1)+(m1+1)*(x[n-1]-x[s])+t*m1%P*(m1+1)%P*(P+1>>1)%P*(n-s-1))%P;
        ans=(ans+(ll)i*(P-i))%P;
        cout<<ans<<endl;
    }
    return 0;
}

上一题