列表

详情


NC54782. 小民与切糕 II

描述

小民今天在小门买了一块切糕,切糕很长,由i个小块组成,第i块有a_i的美味度。
小民吃切糕时,一般会从切糕中取出2段,然后一口吃掉,此时小民得到的满足度为这2段切糕美味度之和的乘积。
现在小民想知道,如果他将所有取法都尝试一遍,总共能够得到多少的满足度。

输入描述

第一行包含一个整数n,表示切糕中块的个数
第二行包含n个整数,第i个整数a_i表示第i块切糕的美味度


输出描述

输出一行一个整数,表示能够得到的总满足度,结果可能过大,请将结果模输出

示例1

输入:

3
1 2 3

输出:

25

说明:

可能的取法:

1*2

1*3

2*3

(1+2)*3

1*(2+3)

原站题解

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

C++14(g++5.4) 解法, 执行用时: 26ms, 内存消耗: 4404K, 提交时间: 2019-11-30 14:43:06

#include<stdio.h>
#include<string.h>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int mod=1e9+7;
ll n,x,b,c;
inline ll read(){
    ll x=0;char ch=' ';ll f=1;
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')f=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*f;
}
ll s[N],p[N],a[N],res[N];
int main(){
//	freopen("D:\\in.txt","r",stdin);
     n=read();
     for(int i=1;i<=n;i++) a[i]=read();
     for(int i=1;i<=n;i++) s[i]=(s[i-1]+i*a[i]%mod)%mod;
	 for(int i=n;i>=1;i--) p[i]=(p[i+1]+(n-i+1)*a[i]%mod)%mod;
	 ll ans=0;
	 for(int i=n;i>=1;i--) res[i]=(res[i+1]+p[i])%mod;
	 for(int i=1;i<=n;i++)
	 ans=(s[i]*res[i+1]%mod+ans)%mod;
	 printf("%lld",ans);
	      
}

C++11(clang++ 3.9) 解法, 执行用时: 30ms, 内存消耗: 3424K, 提交时间: 2020-02-16 17:36:41

#include<bits/stdc++.h>
#include<stdio.h>
#include<string.h>
#define maxn 100005
#define INF 0x3f3f3f3f
#define mst(a) memset(a,0,sizeof a)
#define mststr(a) memset(a,'\0',sizeof a)
#define ll long long
using namespace std;
const ll m=1000000007;
ll a[maxn],R[maxn],L[maxn],sum[maxn];
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	scanf("%lld",a+i);
	for(int i=1;i<=n;i++)
	R[i]=(R[i-1]+a[i]*i)%m;
	for(int i=n;i>0;i--)
	L[i]=(L[i+1]+a[i]*(n-i+1))%m;
	for(int i=n;i>0;i--)
	sum[i]=(sum[i+1]+L[i])%m;
	ll ans=0;
	for(int i=1;i<n;i++)
	ans=(ans+1ll*R[i]*sum[i+1])%m;
	cout<<ans<<endl;
	return 0;
}

上一题