# bzoj 1122: [POI2008]账本BBB（优先队列+贪心）

## 1122: [POI2008]账本BBB

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 517  Solved: 248
[Submit][Status][Discuss]

## Input

The first line contains 5 integers n, p, q, x and y (1 n 1000000, 0 p;q 1000000, 1 x;y 1000), separated by single spaces and denoting respectively: the number of transactions done by Byteasar, initial and final account balance and the number of seconds needed to perform a single turn (change of sign) and move of transaction to the beginning. The second line contains a sequence of n signs (each a plus or a minus), with no spaces in-between. 1 ≤ n ≤ 1000000, 0 ≤ p ,q ≤ 1000000, 1 ≤x,y ≤ 1000)

9 2 3 2 1
---++++++

## Sample Output

3

OK，最后求出最小值

#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
#define LL long long
deque<int> Q;
char str[1000005];
LL a[2000005], b[2000005], sum[2000005];
int main(void)
{
LL n, p, q, x, y, i, ans, now;
scanf("%lld%lld%lld%lld%lld%s", &n, &p, &q, &x, &y, str+1);
for(i=1;i<=n;i++)
a[i] = str[i]=='+'?1:-1;
for(i=n+1;i<=n*2;i++)
a[i] = a[i-n];
for(i=n*2;i>=1;i--)
sum[i] = sum[i+1]+a[i];
n *= 2;
for(i=n;i>=1;i--)
{
if(i<=n/2)
b[i] = sum[i]-sum[Q.back()];
while(Q.empty()==0 && sum[Q.front()]<=sum[i])
Q.pop_front();
Q.push_front(i);
while(Q.back()>=i+n/2)
Q.pop_back();
}
ans = 214748364721474847ll;
n /= 2;
for(i=1;i<=n;i++)
{
now = y*((n-i+1)%n);
if(p+sum[n+1]>=q)
now += (p+sum[n+1]-q)/2*x;
else
{
now += (q-p-sum[n+1])/2*x;
b[i] += (q-p-sum[n+1]);
}
if(p+b[i]<0)
now -= (p+b[i]-1)/2*2*x;
ans = min(ans, now);
}
printf("%lld\n", ans);
return 0;
}
/*
15 0 1 2 3
+--++---++--+++
15 5 0 1 1000
----------+++++
*/