bzoj1122: [POI2008]账本BBB

Description

一个长度为n的记账单,+表示存¥1,-表示取¥1。现在发现记账单有问题。一开始本来已经存了¥p,并且知道最后账户上还有¥q。你要把记账单修改正确,使得 1:账户永远不会出现负数; 2:最后账户上还有¥q。你有2种操作: 1:对某一位取反,耗时x; 2:把最后一位移到第一位,耗时y。

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)

Output

修改消耗的时间

Sample Input

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

Sample Output

3

 

题解:

http://blog.csdn.net/wzq_qwq/article/details/48528159

code:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 char ch;
 8 bool ok;
 9 void read(int &x){
10     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
11     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
12     if (ok) x=-x;
13 }
14 const int maxn=2000005;
15 typedef long long int64;
16 char s[maxn];
17 int n,p,q,x,y,sum[maxn],minv[maxn],tmp,head,tail;
18 int64 ans=1LL<<60;
19 struct Data{
20     int val,id;
21 }que[maxn];
22 int main(){
23     read(n),read(p),read(q),read(x),read(y);
24     scanf("%s",s+1);
25     for (int i=n<<1;i>n;i--) sum[i]=sum[i+1]+(s[i-n]=='+'?1:-1);
26     for (int i=n;i;i--) sum[i]=sum[i+1]+(s[i]=='+'?1:-1);
27     head=1,tail=0;
28     for (int i=n<<1;i;i--){
29         while (head<=tail&&que[head].id>i+n) head++;
30         while (head<=tail&&que[tail].val<sum[i]) tail--;
31         que[++tail]=(Data){sum[i],i};
32         minv[i]=sum[i]-que[head].val;
33     }
34     tmp=(q-p-sum[n+1])>>1;
35     for (int i=1;i<=n;i++){
36         int64 res=1LL*(n-i+1)%n*y+abs(tmp)*x;
37         minv[i]+=p+max(tmp,0)*2;
38         if (minv[i]<0) res+=((1-minv[i])>>1)*x*2;
39         ans=min(ans,res);
40     }
41     printf("%lld\n",ans);
42     return 0;
43 }

 

posted @ 2016-03-07 17:50  chenyushuo  阅读(251)  评论(0编辑  收藏  举报