C. Polycarpus' Dice Codeforces Round #298 (Div. 2)
Polycarp has n dice d1, d2, ..., dn. The i-th dice shows numbers from 1 to di. Polycarp rolled all the dice and the sum of numbers they showed is A. Agrippina didn't see which dice showed what number, she knows only the sum A and the values d1, d2, ..., dn. However, she finds it enough to make a series of statements of the following type: dice i couldn't show number r. For example, if Polycarp had two six-faced dice and the total sum is A = 11, then Agrippina can state that each of the two dice couldn't show a value less than five (otherwise, the remaining dice must have a value of at least seven, which is impossible).
For each dice find the number of values for which it can be guaranteed that the dice couldn't show these values if the sum of the shown values is A.
The first line contains two integers n, A (1 ≤ n ≤ 2·105, n ≤ A ≤ s) — the number of dice and the sum of shown values wheres = d1 + d2 + ... + dn.
The second line contains n integers d1, d2, ..., dn (1 ≤ di ≤ 106), where di is the maximum value that the i-th dice can show.
Print n integers b1, b2, ..., bn, where bi is the number of values for which it is guaranteed that the i-th dice couldn't show them.
2 8
4 4
3 3
1 3
5
4
2 3
2 3
0 1
In the first sample from the statement A equal to 8 could be obtained in the only case when both the first and the second dice show 4. Correspondingly, both dice couldn't show values 1, 2 or 3.
In the second sample from the statement A equal to 3 could be obtained when the single dice shows 3. Correspondingly, it couldn't show 1, 2, 4 or 5.
In the third sample from the statement A equal to 3 could be obtained when one dice shows 1 and the other dice shows 2. That's why the first dice doesn't have any values it couldn't show and the second dice couldn't show 3.
题意:
给出n个骰子和掷出的和A(我代码中的sum),并分别给出n个骰子能掷出的最大数字xi(i=1...n)
求要掷出n个骰子的和为A的所有方案中,每个骰子对应有多少个面用不上。
分析:
设n个骰子都掷出最大数字能达到maxm。
1)考虑第i个骰子掷出的数字尽量小,只有当除了它其它所有都取最大即maxm-d[i]时满足(d[i]为第i个筛子能掷出的最大值)。
此时在掷出的n个数的和为A的前提下,第i个骰子能掷出的下限为sum-(maxm-d[i])。
2)考虑第i个骰子掷出的数字尽量大,那么其它骰子应尽量小即都为1,则在掷出的n个数的和为A的前提下,该骰子能掷出的上限为sum-(n-1)。
3)那么sum-(n-1)和sum-(maxm-d[i])以及d[i]在数轴上的相对位置是如何呢?
由于题目保证合法,即保证sum<=maxm(n个骰子能掷出sum),故可得到sum-(n-1)>1[即sum>n],sum-(maxm-d[i])<=d[i]。
现在只需讨论sum-(n-1)和sum-(maxm-d[i])的大小即可确定1、sum-(n-1)、sum-(maxm-d[i])、d[i]在数轴上的位置(其实就是两个线段的相对位置)。
1、n-1 = maxm-d[i]时,除第i个骰子外其余都是1,或者只有一个骰子i。
这时不能用的点数有d[i]-1个。
2、n-1 < maxm-d[i],则sum-(n-1) > sum-(maxm-d[i]),即两段相交。
此时能用的点数为x = min(d[i],sum-(n-1))-max(1,sum-(maxm-d[i]))。不能用的点数为d[i]-x。
3、n-1 > maxm-d[i],显然不存在(题目保证n个骰子能掷出sum)。
注意 d[i]为10^6,n为2*10^5,要用long long
代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<iostream> #define maxn 200000+5 using namespace std; typedef long long ll; ll d[maxn],ans[maxn]; int main() { ll n,sum; while(~scanf("%I64d%I64d",&n,&sum)) { memset(ans,0,sizeof(ans)); ll maxm = 0; for(int i=0;i<n;i++) { scanf("%I64d",&d[i]); maxm += d[i]; } for(int i=0;i<n;i++) { ll a = sum-(n-1); ll b = sum-(maxm-d[i]); if(a>b) { ans[i] = d[i]-(min(a,d[i])-max(1LL,b)+1); } else if(a==b) { ans[i] = d[i]-1; } } for(int i=0;i<n-1;i++) printf("%I64d ",ans[i]); printf("%I64d\n",ans[n-1]); } return 0; }