【模拟】Codeforces 671B Robin Hood
题目链接:
http://codeforces.com/problemset/problem/671/B
题目大意:
N个人,每个人有Ci钱,现在有一个人劫富济贫,从最富的人之一拿走1元,再给最穷的人。总共K次,问最后贫富差距。
钱被拿走是立刻结算,所以可能拿走后这个人变最穷的人再还回去。
最富或最穷的人可能有多个,随机选择,并且不会影响最终答案。
(1 ≤ n ≤ 500 000, 0 ≤ k ≤ 109)
题目思路:
【模拟】
直接排序离散化数据,之后模拟就行。
细节挺多的要处理清楚。
1 // 2 //by coolxxx 3 //#include<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string> 7 #include<iomanip> 8 #include<map> 9 #include<memory.h> 10 #include<time.h> 11 #include<stdio.h> 12 #include<stdlib.h> 13 #include<string.h> 14 //#include<stdbool.h> 15 #include<math.h> 16 #define min(a,b) ((a)<(b)?(a):(b)) 17 #define max(a,b) ((a)>(b)?(a):(b)) 18 #define abs(a) ((a)>0?(a):(-(a))) 19 #define lowbit(a) (a&(-a)) 20 #define sqr(a) ((a)*(a)) 21 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b)) 22 #define mem(a,b) memset(a,b,sizeof(a)) 23 #define eps (1e-8) 24 #define J 10 25 #define mod 1000000007 26 #define MAX 0x7f7f7f7f 27 #define PI 3.14159265358979323 28 #define N 500004 29 using namespace std; 30 typedef long long LL; 31 int cas,cass; 32 int n,m,lll,ans; 33 double anss; 34 LL b[N]; 35 LL sum; 36 struct xxx 37 { 38 LL num,large; 39 }a[N]; 40 bool cmp(LL aa,LL bb) 41 { 42 return aa<bb; 43 } 44 int work() 45 { 46 int i; 47 LL k,maxx,minn; 48 k=m;i=lll; 49 while(i && k>=a[i].num*(a[i].large-a[i-1].large)) 50 { 51 k-=a[i].num*(a[i].large-a[i-1].large); 52 a[i-1].num+=a[i].num; 53 a[i--].num=0; 54 if(!i)return (sum%n!=0); 55 } 56 maxx=a[i].large-k/a[i].num; 57 a[i+1].large=maxx,a[i+1].num=a[i].num-k%a[i].num; 58 a[i].large=maxx-1;a[i].num-=a[i+1].num; 59 lll=i+1; 60 //========================================== 61 k=m;i=1; 62 while(k>0 && k>=a[i].num*(a[i+1].large-a[i].large) && a[i].large<maxx) 63 { 64 if(a[i].num==0){i++;continue;} 65 k-=a[i].num*(a[i+1].large-a[i].large); 66 a[i+1].num+=a[i].num; 67 a[i++].num=0; 68 } 69 if(a[i].large>=maxx)return (sum%n!=0); 70 if(a[i+1].num==0) 71 minn=a[i].large+k/a[i].num; 72 else 73 minn=a[i].large+k/(a[i].num); 74 return maxx-minn; 75 } 76 int main() 77 { 78 #ifndef ONLINE_JUDGE 79 freopen("1.txt","r",stdin); 80 // freopen("2.txt","w",stdout); 81 #endif 82 int i,j; 83 // for(scanf("%d",&cas);cas;cas--) 84 // for(scanf("%d",&cas),cass=1;cass<=cas;cass++) 85 // while(~scanf("%s",s)) 86 while(~scanf("%d",&n)) 87 { 88 scanf("%d",&m); 89 sum=0;mem(a,0); 90 for(i=1;i<=n;i++) 91 { 92 scanf("%d",&b[i]); 93 sum+=b[i]; 94 } 95 sort(b+1,b+1+n,cmp); 96 lll=1;a[lll].large=b[1];a[lll].num=1; 97 for(i=2;i<=n;i++) 98 { 99 if(b[i]==b[i-1])a[lll].num++; 100 else a[++lll].large=b[i],a[lll].num=1; 101 } 102 j=work(); 103 printf("%d\n",j); 104 } 105 return 0; 106 } 107 /* 108 // 109 110 // 111 */