黑龙江大学程序设计竞赛(重现赛)B:Help Me(数学)

14 篇文章 0 订阅
6 篇文章 0 订阅

链接:https://ac.nowcoder.com/acm/contest/877/B
来源:牛客网

有一天Miss Quan出了一个题,给出一个长度为的数组

Miss Quan说给我计算下这个权值等于多少,然后随手写了一个式子,把她的小伙伴们都给惊呆了,这是什么鬼…
在这里插入图片描述
比如 N = 2 , V a l u e = ( a 2 − a 1 ) 2 + ( a 3 − a 1 ) 2 + ( a 3 − a 2 ) 2 N=2,Value=(a_2-a_1)^2+(a_3-a_1)^2+(a_3-a_2)^2 N=2,Value=(a2a1)2+(a3a1)2+(a3a2)2
听到这里,小伙伴们说这不是很简单吗,于是写出了下面的代码:
在这里插入图片描述
Miss Quan会心一笑,大家意识到事情并不简单,这个解法时间复杂度太高了,你能想出更好的计算Value的方法吗?只需要输出Value的值即可。

输入描述

第一行输入一个整数代表共有 T T T组数据 T ( 1 ≤ T ≤ 50 ) T(1\leq T\leq 50) T(1T50)
对于每组测试用例第一行输入一个整数 n ( 2 ≤ n ≤ 50000 ) n(2\leq n \leq 50000) n(2n50000)第二行输入 n n n个数 a 1 , a 2 , a 3 , … , a n ( 1 ≤ a i ≤ 1 0 4 ) a_1,a_2,a_3,\dots,a_n(1\leq a_i \leq 10^4) a1,a2,a3,,an(1ai104)

输出描述

对于每组数据,输出一行,一个整数 V a l u e Value Value代表的值.

示例1

输入

2
3
1 4 2
2
10 20

输出

14
100

示例2

输入

1
4
5 6 8 7

输出

20

Solve

通过对上述公式化简,可以得到:
V a l u e = ( n − 1 ) × ∑ i = 1 n a i 2 − 2 × ( ∑ i = 1 n − 1 ( a i × ∑ j = i + 1 n a j ) ) Value=(n-1)\times \sum_{i=1}^{n} a_{i}^{2}-2\times (\sum_{i=1}^{n-1}(a_i\times \sum_{j=i+1}^{n}a_j)) Value=(n1)×i=1nai22×(i=1n1(ai×j=i+1naj))
然后用前缀和处理一下 ∑ j = i + 1 n a j \sum_{j=i+1}^{n}a_j j=i+1naj的值,可以得到最终公式:
V a l u e = ( n − 1 ) × ∑ i = 1 n a i 2 − 2 × ( ∑ i = 1 n − 1 a i × s u m n − s u m i ) Value=(n-1)\times \sum_{i=1}^{n} a_{i}^{2}-2\times (\sum_{i=1}^{n-1}a_i\times sum_n-sum_i) Value=(n1)×i=1nai22×(i=1n1ai×sumnsumi)

Code

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ms(a,b) memset(a,b,sizeof(a))
#define INF 0x7f7f7f7f
const int maxn=1e6+10;
const int mod=1e9+7;
using namespace std;
ll a[maxn];
ll sum[maxn];
int main(int argc, char const *argv[])
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin>>t;
    while(t--)
    {
        ms(sum,0);
        int n;
        cin>>n;
        ll value=0;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            value+=(n-1)*a[i]*a[i];
            sum[i]=sum[i-1]+a[i];
        }
        for(int i=1;i<n;i++)
            value-=2*a[i]*(sum[n]-sum[i]);
        cout<<value<<endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值