XTUOJ 15503 - C

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,表示样例个数($t\leq 10$)。每组样例第一行有四个整数 $n,m,x,y (1\leq n,m\leq 200000,1\leq x,y\leq 10^9)$.第二行有n个整数 $a_1,a_2,…,a_n (1\leq a_i\leq 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\n",LL(m)*x + (a[0] + y));
48             continue;
49         }
50         printf("%I64d\n",solve(y));
51     }
52     return 0;
53 }
54 /*
55 1
56 5 4 8 4
57 1 5 5 7 8
58 */
View Code

 

posted @ 2015-10-21 13:14  狂徒归来  阅读(291)  评论(0编辑  收藏  举报