2017四川省赛 L.Nice Trick【Dp+逆元】

来源:互联网 发布:生意参谋怎么看数据 编辑:程序博客网 时间:2024/06/04 18:19

题面下载:https://icpc-camp-cdn.b0.upaiyun.com/permanent/problems/sichuan-2017.pdf



题目大意:


现在给你S3的求法,让你求S4.


思路:


我们设定dp【i】表示S4的值。


肯定S4和S3是有相关性的。我们不妨尝试递推一下状态转移方程。


不难推出,dp【i】=dp【i-1】+a【i】*S3【i-1】;


过程注意取模以及除法取模要求个逆元就没别的什么了。


Ac代码:

#include<stdio.h>#include<string.h>using namespace std;#define ll long long intconst ll mod=1e9+7;ll A[150000];ll B[150000];ll C[150000];ll a[150000];ll sum[150000];ll dp[150000];ll extend_euclid(ll a,ll b,ll &x,ll &y){    if(b==0)    {        x=1,y=0;        return a;    }    else    {        ll r = extend_euclid(b,a%b,x,y);        ll t = x;        x = y;        y = t - (a/b)*y;        return r;    }}ll chufaqumo(int fenzi ,int fenmu){    ll x,y;    extend_euclid(fenmu,mod,x,y);    x=(x%mod+mod)%mod;    x=(x*fenzi+mod)%mod;    return x;}int main(){    int n;    while(~scanf("%d",&n))    {        memset(A,0,sizeof(A));        memset(B,0,sizeof(B));        memset(C,0,sizeof(C));        memset(sum,0,sizeof(sum));        memset(dp,0,sizeof(dp));        for(int i=1;i<=n;i++)scanf("%lld",&a[i]);        for(int i=1;i<=n;i++)        {            A[i]=(A[i-1]+(((a[i]*a[i])%mod)*a[i])%mod)%mod;            B[i]=(B[i-1]+(a[i]*a[i])%mod)%mod;            C[i]=(C[i-1]+a[i])%mod;            sum[i]=(((C[i]*C[i])%mod)*C[i])%mod;            sum[i]-=3*B[i]*C[i];            sum[i]=(sum[i]%mod+mod)%mod;            sum[i]=(sum[i]+2*A[i])%mod;            sum[i]=chufaqumo(sum[i],6);        }        for(int i=1;i<=4;i++)        {            if(i==1)dp[i]=a[i];            else dp[i]=(dp[i-1]*a[i])%mod;        }        for(int i=5;i<=n;i++)        {            dp[i]=dp[i-1]+(a[i])*sum[i-1];            dp[i]%=mod;        }        if(n<=3)        {            printf("0\n");            continue;        }        printf("%lld\n",dp[n]);    }}






原创粉丝点击