15503 - C
Accepted: 6 Submissions: 27 Time Limit: 3000 ms Memory Limit: 1048576 KB
在解决了小女孩的谜题后,小女孩很大方的告诉了deemo她的名字:Alice。
从此deemo不再孤单一人了。他们每天快乐的生活在一起。deemo平时喜欢弹钢琴,Alice会静静的坐在他的身边,看deemo以前看过的书。
“deemo,你的书里的谜题都好难啊。”Alice歪着脑袋愁眉苦脸的看着书。
“想知道答案可以问我,我都解决了。”deemo的琴声欢快了起来。
“真的?这么厚的一本书?,那这题你知道答案吗?”
“嗯,因为在你来之前,我都是一个人。”
谜题:
n个人在玩一个关于蜡烛的游戏。这些人编号为1,2,…,n。一开始,第i个人有ai根蜡烛在手上。
这个游戏进行m轮。在每一轮,蜡烛最少的人可以获得x根蜡烛。如果有多于两个人有最少的蜡烛,则编号最小的人获得蜡烛。
编号为1的是他们的老大。所以他可以在游戏开始前从其他途径多获得y根蜡烛。现在他想知道他在m轮之后最多可以拥有多少根蜡烛。
Input
一个整数t,表示样例个数($tleq 10$)。每组样例第一行有四个整数 $n,m,x,y (1leq n,mleq 200000,1leq x,yleq 10^9)$.第二行有n个整数 $a_1,a_2,…,a_n (1leq a_ileq 10^9)$.
Output
每组样例一个整数表示蜡烛的最大数量。
Input
1
2 1 2 2
1 2
Output
4
Source
XTU OnlineJudge
解题:假设不把$a_0$放进去,我们可以通过x和y使得a[0]等于剩余的某个数的现在的值,这样搞下去即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 200010; 4 typedef long long LL; 5 typedef pair<LL,int> PLI; 6 priority_queue<PLI,vector<PLI >,greater<PLI > >p,q; 7 int cnt[maxn],n,m,x,y; 8 LL a[maxn]; 9 LL solve(int st,LL ret = 0) { 10 while(!q.empty()) q.pop(); 11 while(!p.empty()) p.pop(); 12 memset(cnt,0,sizeof cnt); 13 for(int i = 1; i < n; ++i) { 14 q.push(PLI(a[i],i)); 15 p.push(PLI(a[i],i)); 16 } 17 p.push(PLI(a[0] + st,0)); 18 ret = a[0]; 19 for(int i = 0; i < m; ++i) { 20 PLI now = q.top(); 21 q.pop(); 22 if(now.first >= a[0]){ 23 LL k = ceil(double(now.first - a[0] - y)/x); 24 if(i + max(k,0LL) + 1 <= m && a[0] + k*x <= now.first) 25 ret = max(ret,now.first + x); 26 } 27 now.first += x; 28 q.push(now); 29 } 30 ret = max(ret,a[0] + st); 31 for(int i = 0; i < m; ++i) { 32 PLI now = p.top(); 33 now.first += x; 34 p.pop(); 35 if(now.second == 0) ret = max(ret,now.first); 36 p.push(now); 37 } 38 return ret; 39 } 40 int main() { 41 int kase; 42 scanf("%d",&kase); 43 while(kase--) { 44 scanf("%d%d%d%d",&n,&m,&x,&y); 45 for(int i = 0; i < n; ++i) scanf("%I64d",a + i); 46 if(n == 1) { 47 printf("%I64d ",LL(m)*x + (a[0] + y)); 48 continue; 49 } 50 printf("%I64d ",solve(y)); 51 } 52 return 0; 53 } 54 /* 55 1 56 5 4 8 4 57 1 5 5 7 8 58 */