http://codeforces.com/problemset/problem/1141/C
An array of integers p1,p2,…,pnp1,p2,…,pn is called a permutation if it contains each number from 11 to nn exactly once. For example, the following arrays are permutations: [3,1,2][3,1,2] , [1][1] , [1,2,3,4,5][1,2,3,4,5] and [4,3,1,2][4,3,1,2] . The following arrays are not permutations: [2][2] , [1,1][1,1] , [2,3,4][2,3,4] .
Polycarp invented a really cool permutation p1,p2,…,pnp1,p2,…,pn of length nn . It is very disappointing, but he forgot this permutation. He only remembers the array q1,q2,…,qn−1q1,q2,…,qn−1 of length n−1n−1 , where qi=pi+1−piqi=pi+1−pi .
Given nn and q=q1,q2,…,qn−1q=q1,q2,…,qn−1 , help Polycarp restore the invented permutation.
Input
The first line contains the integer nn (2≤n≤2⋅1052≤n≤2⋅105 ) — the length of the permutation to restore. The second line contains n−1n−1 integers q1,q2,…,qn−1q1,q2,…,qn−1 (−n<qi<n−n<qi<n ).
Output
Print the integer -1 if there is no such permutation of length nn which corresponds to the given array qq . Otherwise, if it exists, print p1,p2,…,pnp1,p2,…,pn . Print any such permutation if there are many of them.
Examples
Input
3 -2 1
Output
3 1 2
Input
5 1 1 1 1
Output
1 2 3 4 5
Input
4 -1 2 2
Output
-1
题目大意: 给出n-1个数:q1、q2……q(n-1), 且qi=p(i+1)-pi,, 序列p有n个数, 是n的全排列,问你能否通过序列q还原出满足题意的序列p, 若能输出序列p, 否则输出-1。
思路: 一道水题居然卡了半天……以后智商不在线不打CodeForces了orz。已知:p1=q2-q1、p2=q3-q2……我们计算序列p的前缀和, 那么sum[1]=p2-p1,sum[2]=p3-p1……sum[n-1]=pn-p1, 又序列p是n的全排列, 因此若能还原出满足题意的序列p,则sum[1]到sum[n-1]必定均不相同,那么若存在sum[i]==0||sum[i]>=n||sum[i]<=-n的情况,必定是不满足题意的。 在计算sum数组的同时我们用MIN记录sum[i]的最小值, 若MIN<0,则我们对sum数组做平移操作, 即sum[i]-=MIN,然后遍历sum数组同时做标记, 若[0,n-1]的某个数被标记了两次, 那么这也是不满足题意的情况, 否则p1就等于[0, n-1]中未被标记的那个数+1。(这个规律还是很好找的 自己试一下就知道了 注意要用long long)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
ll a[200005];
ll sum[200005];
int vis[200005];
ll t=0;
int main()
{
int n;
scanf("%d",&n);
int flag=0;
ll MIN=0;
ll temp;
for(int i=1;i<=n-1;i++)
{
scanf("%lld",&temp);
sum[i]=sum[i-1]+temp;
a[i]=sum[i];
if(a[i]==0||a[i]>=n||a[i]<=-n)
flag=1;
MIN=min(MIN,sum[i]);
}
if(MIN<0)
{
for(int i=1;i<=n-1;i++)
a[i]-=MIN;
}
for(int i=1;i<=n-1;i++)
{
if(a[i]>=n||vis[a[i]])
flag=1;
else
vis[a[i]]=1;
}
if(flag)
printf("-1\n");
else
{
t=0;
for(int i=1;i<=n-1;i++)
if(!vis[i])
t=i;
t+=1;
for(int i=1;i<=n;i++)
{
if(i==1)
printf("%lld",t);
else
printf(" %lld",t+sum[i-1]);
}
}
}