(File IO): input:fett.in output:fett.out
时间限制: 1000 ms 空间限制: 128000 KB 具体限制
Goto ProblemSet
题目描述
从前有一条神奇的项链,为什么说它神奇呢?因为它有两个性质:
- 神奇的项链可以拉成一条线,线上依次是 N N N个珠子,每个珠子有一个能量值 E i Ei Ei;
- 除了第一个和最后一个珠子,其他珠子都满足
E
i
=
(
E
i
−
1
+
E
i
+
1
)
/
2
+
D
i
Ei=(Ei-1+Ei+1)/2+Di
Ei=(Ei−1+Ei+1)/2+Di。
由于这条项链很长,我们只能知道其两端珠子的能量值。并且我们知道每个珠子的 D i Di Di是多少。请聪明的你求出这 N N N个珠子的能量值分别是多少。
输入
第一行三个整数
N
、
E
1
、
E
N
,
N、E1、EN,
N、E1、EN,表示珠子个数
N
N
N,第一个珠子和第
N
N
N 个珠子的能量值。
第二行
N
−
2
N-2
N−2 个整数,表示第
2
2
2 个珠子到第
N
−
1
N-1
N−1个珠子的
D
i
Di
Di。
输出
输出仅一行,
N
N
N 个整数,表示
1
1
1 到
N
N
N 个这
N
N
N 个珠子各自的能量值
E
i
Ei
Ei。
请放心,数据保证对于任意珠子满足
(
E
i
−
1
+
E
i
+
1
)
M
o
d
2
=
0
(Ei-1+Ei+1)Mod 2=0
(Ei−1+Ei+1)Mod2=0
样例输入
Sample Input 1:
4 1 4
0 0
Sample Input 2:
10 1 22
1 2 -3 5 1 4 2 -1
样例输出
Sample Output 1:
1 2 3 4
Sample Output 2:
1 14 25 32 45 48 49 42 31 22
数据范围限制
40
40
40%的数据
1
<
N
<
=
100
1<N<=100
1<N<=100。
70
70
70%的数据
1
<
N
<
=
5
,
000
1<N<=5,000
1<N<=5,000,所有数据(包括计算中的)不超过
1
0
9
10^9
109。
100
100
100%的数据
1
<
N
<
=
500
,
000
1<N<=500,000
1<N<=500,000,
∣
E
1
∣
、
∣
E
N
∣
<
=
1
0
1
4
,
∣
D
i
∣
<
=
1
0
4
|E1|、|EN|<=10^14,|Di|<=10^4
∣E1∣、∣EN∣<=1014,∣Di∣<=104。
解题思路
二分答案
通过
E
i
=
(
E
i
−
1
+
E
i
+
1
)
/
2
+
D
i
Ei=(Ei-1+Ei+1)/2+Di
Ei=(Ei−1+Ei+1)/2+Di,我们可以推出
E
i
+
1
=
(
E
i
−
D
i
)
∗
2
−
E
i
−
1
Ei+1=(Ei-Di)*2-Ei-1
Ei+1=(Ei−Di)∗2−Ei−1
也就是说知道E2就知道全部
二分
E
2
E2
E2
如果
E
n
En
En和输入进来的一样,就输出
代码
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<cmath>
using namespace std;
long long n,b,d[500010],a[500010];
long long l=-2147483647,r=-l,k,mid;
int main(){
freopen("fett.in","r",stdin);
freopen("fett.out","w",stdout);
scanf("%lld%lld%lld",&n,&a[1],&k);
for(int i=2;i<n;i++)
scanf("%lld",&d[i]);
while(l<=r){
mid=(l+r)/2;
a[2]=mid;
for(long long i=2;i<n;i++){
a[i+1]=(a[i]-d[i])*2-a[i-1];
}
if(a[n]==k)
{
for(long long i=1;i<=n;i++)
printf("%lld ",a[i]);
return 0;
}
if(a[n]>k)
r=mid;
else
l=mid;
}
return 0;
}