BZOJ-1811 [Ioi2005]mea(解方程)
阿新 • • 發佈:2020-12-09
題目描述
考慮一個非遞減的整數序列 \(S_1,\cdots,S_{n+1}(S_i \leq S_{i+1},1\leq i\leq n)\)。序列 \(M_1 \cdots M_n\) 是定義在序列 \(S\) 的基礎上,關係式為 \(M_i=\frac{S_i+S_{i+1}}{2}(1\leq i<n)\),序列 \(M\) 叫做序列 \(S\) 的平均數序列。
例如序列 \(1,2,2,4\) 的平均數序列為 \(1.5,2,3\)。注意到平均數序列中的元素可能為小數。但是本題的任務只是處理平均數序列都為整數的情況。
給出一個 \(n\) 個數字的非遞減的整數序列 \(M_1,M_2,\cdots,M_n\)
資料範圍:\(2\leq n\leq 5\times 10^6,1\leq M_i\leq 10^9\)。
分析
只要確定了序列第一個數字 \(S_1\),則其他 \(S_i\) 都可以用含 \(S_1\) 的式子表示出來,設 \(S_1=x\)。
\[\begin{aligned}&S_1=x\\&S_2=2M_1-S_1=2M_1-x\\&S_3=2M_2-S_2=2(-M_1+M_2)+x\\&S_4=2M_3-S_3=2(M_1-M_2+M_3)-x\\&\cdots\\&S_{i-1}=2M_{i-2}-S_{i-2}=2(-M_1+M_2-\cdots+M_{i-2})+x\\&S_i=2M_{i-1}-S_{i-1}=2(M_1-M_2+M_3-\cdots+M_{i-1})-x(i為偶數)\end{aligned} \]由於 $S_i\leq S_{i+1}(1\leq i\leq n) $,可以列出以下 \(n\) 個不等式(設 \(c_i=M_1-M_2+\cdots-M_{i}\)):
\[\begin{aligned}&S_1\leq S_2\Longrightarrow x\leq M_1\\&S_2\leq S_3\Longrightarrow 2M_1-M_2\leq x\\&S_3\leq S_4\Longrightarrow x\leq 2M_1-2M_2+M_3\\&\cdots\\&S_{i-1}\leq S_{i}\Longrightarrow x\leq 2c_{i-2}+M_{i-1}\\&S_{i}\leq S_{i+1}\Longrightarrow 2c_{i-1}-M_{i}\leq x(i為偶數)\end{aligned} \]維護 \(L=\max(L,2c_{i-1}-M_i)(i\%2=0),R=\min(R,2c_{i-1}+M_i)(i\%2=1)\),答案為 \(\max(R-L+1,0)\)。
程式碼
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
const int N=5e6+10;
long long c[N],M[N];
int main()
{
int n=read();
long long L=-1ll<<60,R=1ll<<60,ans=0;
for(int i=1;i<=n;i++)
{
M[i]=read();
if(i%2==1)
ans=ans+M[i];
else
ans=ans-M[i];
c[i]=ans;
}
for(int i=1;i<=n;i++)
{
if(i%2==1)
R=min(R,2*c[i-1]+M[i]);
else
L=max(L,2*c[i-1]-M[i]);
}
//cout<<L<<" "<<R<<endl;
cout<<max(R-L+1,0ll)<<endl;
return 0;
}