Problem H. Hell on the Markets
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=86821#problem/H
Description
Most financial institutions had become insolvent during financial crisis and went bankrupt or were bought by larger institutions, usually by banks. By the end of financial crisis of all the financial institutions only two banks still continue to operate. Financial markets had remained closed throughout the crisis and now regulators are gradually opening them. To prevent speculation and to gradually ramp up trading they will initially allow trading in only one financial instrument and the volume of trading will be limited to i contracts for i-th minute of market operation. Two banks had decided to cooperate with the government to kick-start the market operation. The boards of directors had agreed on trading volume for each minute of this first trading session. One bank will be buying ai contracts (1 ≤ ai ≤ i) during i-th minute (1 ≤ i ≤ n), while the other one will be selling. They do not really care whether to buy or to sell, and the outside observer will only see the volume ai of contracts traded per minute. However, they do not want to take any extra risk and want to have no position in the contract by the end of the trading session. Thus, if we define bi = 1 when the first bank is buying and bi = −1 when the second one is buying (and the first one is selling), then the requirement for the trading session is that Pn i=1 aibi = 0. Your lucky team of three still works in the data center (due to the crisis, banks now share the data center and its personnel) and your task is to find such bi or to report that this is impossible.
Input
The first line of the input file contains the single integer number n (1 ≤ n ≤ 100 000). The second line of the input file contains n integer numbers — ai (1 ≤ ai ≤ i).
Output
The first line of the output file must contain “Yes” if the trading session with specified volumes is possible and “No” otherwise. In the former case the second line must contain n numbers — bi
Sample Input
4
1 2 3 4
Sample Output
Yes
1 -1 -1 1
HINT
题意
给你n个数,让你构造一个bi,bi的取值不是1
然后满足ai*bi的累加等于0
题解:
注意题意,a[i]<=i,所以先排一个序,然后就可以贪心弄了
每一个数不是属于第一组,就是属于第二组
然后貌似就可以贪心了?反正这个贪心是猜的……
测了几组数据,发现是对的
群里的老司机给了一个证明:
对于1≤ai≤i+1,前面ai的数一定可以表示出1~sum[i]中的任意一个数. 对于i=1显然成立, 假设对于i=k结论成立,那么对于i=k+1来说,只要证明sum[k]+i,1≤i≤ak+1可以凑出来就行了。 因为sum[k]+i≥k+1,且1≤ak+1≤k+1,所以可以先选一个ak+1,剩下的0≤sum[k]+i-ak+1≤sum[k]一定是可以由前面的数字凑出来的。
代码:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <vector> #include <stack> #include <map> #include <set> #include <queue> #include <iomanip> #include <string> #include <ctime> #include <list> typedef unsigned char byte; #define pb push_back #define input_fast std::ios::sync_with_stdio(false);std::cin.tie(0) #define local freopen("in.txt","r",stdin) #define pi acos(-1) using namespace std; const int maxn = 1e5 + 500; int n; typedef struct data { int val; int idx; friend bool operator < (const data & x,const data & y) { return x.val < y.val; } }; data A[maxn]; long long sum = 0; long long L = 0 , R = 0; int ans[maxn]; int main(int argc,char *argv[]) { freopen("hell.in","r",stdin); freopen("hell.out","w",stdout); scanf("%d",&n); for(int i = 0 ; i < n ; ++ i) { scanf("%d",&A[i].val); A[i].idx = i; sum += A[i].val; } sort(A,A+n); if (sum & 1 ) printf("No\n"); else { for(int i = n-1 ; i >= 0 ; -- i) { if (L < R) { L += A[i].val; ans[A[i].idx] = -1; } else { R += A[i].val; ans[A[i].idx] = 1; } } if (L == R) { printf("Yes\n"); printf("%d",ans[0]); for(int i = 1 ; i < n ; ++ i) printf(" %d",ans[i]); printf("\n"); } else printf("No\n"); } return 0; }