P8920
『MdOI R5』Variance
题目描述
给定两个长度为 \(n\) 的整数序列 \(a,b\),满足:
-
\(\forall i\in [1,n),a_i\le a_{i+1},b_i\le b_{i+1}\)。
-
\(\forall i\in [1,n],a_i\le b_i\)。
有一个长度为 \(n\) 的实数序列 \(c\),满足 \(c_i\in [a_i,b_i]\),求 \(c\) 的方差的最大值。
你只需要输出答案乘上 \(n^2\) 之后的结果。容易证明这是一个整数。
提示
一个长度为 \(n\) 的序列 \(a\) 的方差为:\(\dfrac{1}{n}\sum\limits_{i=1}^n (a_i-\overline{a})^2\)。其中 \(\overline{a}=\dfrac{1}{n}\sum\limits_{i=1}^n a_i\)。
本题的计算过程中可能会涉及到超过 long long 范围的数,此时可能需要用到 __int128 进行处理。
我们提供了以下代码,它可以用于输出一个 __int128 类型的数:
void print(__int128 x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x<10)
{
putchar(x+48);
return;
}
print(x/10);
putchar(x%10+48);
}
输入格式
第一行,一个整数,表示 \(n\)。
第二行,\(n\) 个整数,表示 \(a_1,a_2,\dots,a_n\)。
第三行,\(n\) 个整数,表示 \(b_1,b_2,\dots,b_n\)。
输出格式
共一行,一个整数,表示答案。
样例 #1
样例输入 #1
2
1 10
1 10
样例输出 #1
81
样例 #2
样例输入 #2
3
1 2 3
3 4 5
样例输出 #2
26
提示
对于 \(100\%\) 的数据,\(1\le n\le 10^6\),\(1\le a_i,b_i\le 10^9\)。
\(\operatorname{Subtask} 1(10\%)\):\(n\le 2\times 10^3\),\(a_i=b_i\le 10^5\)。
\(\operatorname{Subtask} 2(20\%)\):\(n\le 10\),\(a_i,b_i\le 5\)。
\(\operatorname{Subtask} 3(20\%)\):\(n\le 2\times 10^3\),\(a_i,b_i\le 10^5\)。
\(\operatorname{Subtask} 4(20\%)\):\(n\le 10^5\),\(a_i,b_i\le 2\times 10^3\)。
\(\operatorname{Subtask} 5(30\%)\):无特殊限制。
样例说明 1
\(c\) 只可能为 \((1,10)\)。
样例说明 2
一种最优的 \(c\) 为 \((1,2,5)\)。
Solution:
最开始的想法基本正确:
观察样例可以发现肯定是a[]取前面连续若干个 b[]取后面连续若干个(虽然最开始想的是b[]只取最后一个)
然后就可以枚举分界点i 用前缀和优化计算所求式子 更新答案即可
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int __int128
inline void read(int &n){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
n=x*f;
}
void print(__int128 x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x<10)
{
putchar(x+48);
return;
}
print(x/10);
putchar(x%10+48);
}
__int128 n,a,b;
__int128 ans=0,s1[1000005],s2[1000005],s3[1000005],s4[1000005];
signed main()
{
ios::sync_with_stdio(false);
read(n);
for(int i=1;i<=n;i++)read(a),s1[i]=s1[i-1]+a,s3[i]=s3[i-1]+a*a;
for(int i=1;i<=n;i++)read(b),s2[i]=s2[i-1]+b,s4[i]=s4[i-1]+b*b;
__int128 now_ans;
for(int i=1;i<=n-1;i++)
{
now_ans=(n*(s3[i]+s4[n]-s4[i])-(s1[i]+s2[n]-s2[i])*(s1[i]+s2[n]-s2[i]));
ans=max(ans,now_ans);
}
now_ans=(n*s3[n]-s1[n]*s1[n]);
ans=max(ans,now_ans);
now_ans=(n*s4[n]-s2[n]*s2[n]);
ans=max(ans,now_ans);
print(ans);
return 0;
}
# **很多题猜到大概结论后就勇敢地写!!!**

浙公网安备 33010602011771号