Problem: Easy to improve
Time limit: 1s Mem limit: 64 MB
There are n numbers in array a and a function f whose code is:
ans = 0;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
ans += pow (a[i]+a[j], 3);
ans %= 1000000007;
}
}
return ans;
JieBa said, it's easy to improve the time complexity. So what's the
final answer (module 1000000007)?
There are T groups of test data. The first line contains one positive integer T (1<=T<=100).
For each test data : the first line contains a single integer n (2<=n<=100000), next line contains n numbers: a[0] to a[n-1] (0<=a[i]<=100000).
For each case, output the answer in one line.
优化算法
ans = 0;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
ans += pow (a[i]+a[j], 3);
ans %= 1000000007;
}
}
return ans;
思路:
易知,计算每个数到之后每个数的立方和,与每个数到之前每个数的立方和,结果不变。
设有a1, a2, a3, a4, a5, 计算到a5, 即计算 (a1 + a5)2 + (a2 + a5)2 + (a3 + a5)2 + (a4 + a5)2 把 a5整理出来就可以得到公式啦~
注意点:
1、灵活变换题目,发现从后往前与从前往后计算方法一样
2、大数据的处理,之前代码怎么也AC不了, 在循环中多加了好几个%mod 就可以了
3、熟练用typedef long long ll 将long long变为ll来做,可以加快做题速度。
改善:
发现自己想复杂了,可以合并成(a1 + a2 +……+a5) * (a1 * a1 + a2 * a2 + a3 * a3 +……+a5*a5) 的。噗 ==。
把学长更优化的代码贴在了下面的下面了
#include <iostream>
#include<stdio.h>
#include <cstdio>
#include <cstring>
#include <math.h>
using namespace std;
typedef unsigned long long LL;
#define mm(a) memset((a), 0, sizeof(a))
LL a[110000];
LL tri[110000];
LL dou[110000];
LL sing[110000];
LL n;
const LL mod = 1e9 + 7;
LL ppow(LL n, LL m) {
LL ans = 1;
while (m) {
if (m % 2) ans = (ans * n) % mod;
n = n * n % mod;
m /= 2;
}
return ans % mod;
}
LL fff() {
LL ans = 0;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
//ans += pow((a[i] + a[j]) % mod , 3);
ans += ppow((a[i] + a[j]) % mod, 3);
ans %= mod;
}
}
return ans;
}
int main() {
// freopen("1.txt", "r", stdin);
LL T;
cin >> T;
while (T --) {
mm(tri);
mm(sing);
mm(dou);
mm(a);
cin >> n;
tri[0] = dou[0] = sing[0] = 0;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
tri[i] = ppow(a[i], 3) + tri[i - 1];
dou[i] = ppow(a[i], 2) + dou[i - 1];
sing[i] = a[i] + sing[i - 1];
sing[i] %= mod;
}
LL ans = 0;
for (int i = 2; i <= n; i++) {
ans += ((i - 1) * ppow(a[i], 3)) % mod;
ans += tri[i - 1] % mod;
ans += (3 * a[i] % mod * dou[i - 1]) % mod;
ans += (3 * a[i] % mod * a[i] % mod * sing[i - 1]) % mod;
ans %= mod;
}
cout << ans << endl;
//cout << fff() << endl;
}
return 0;
}
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const long long mod=1e9+7;
const int maxn=1e5+10;
long long a[maxn];
int n;
int main()
{
int t;
cin>>t;
while (t--)
{
cin>>n;
for (int i=0;i<n;i++) cin>>a[i];
long long sum1=0,sum2=0,sum3=0;
for (int i=0;i<n;i++)
{
sum1=(sum1+a[i])%mod;
sum2=(sum2+a[i]*a[i])%mod;
sum3=(sum3+a[i]*a[i]*a[i])%mod;
}
long long res=(n-4)*sum3%mod;
res%=mod;
res+=3*sum2*sum1%mod;
res%=mod;
cout<<res<<endl;
}
return 0;
}