The question is: given a +1 And ? 1 The length of the composition is n Sequence, which provides two kinds of operations:
1. To reverse one of the costs x
2. Move the last one to the previous one, spending y
Demand final P+su m n =q And P+su m i ≥0(1≤I≤N) For minimum expenses
Enumerates the point at which the final sequence begins, the smallest prefix from this point back and can be preprocessed with a monotone queue
And then greedy to the left. ? 1 Change into +1 , on the right +1 Change into ? 1 Until you meet the requirements
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 2002002using namespace Std;intN,p,Q; Long Longx,y, ans=0x7fffffffffffffffLl;chars[M];intSum[m],_min[m];void Assert (BOOL flag) {if(flag)return;printf("%d\ n",1/0);Exit(0);}intMain () {intI Cin>>n>>p>>Q>>x>>y; scanf'%s',s+1); for(i=n<<1; i>n;i--) sum[i]=sum[i+1]+(s[i-n]=='-'?-1:1); for(i=n;i;i--) sum[i]=sum[i+1]+(s[i]=='-'?-1:1); Staticint Q[m], R,h; for(i=n<<1; i;i--) { while(r-h>=1&& sum[Q[r]]<sum[i])q[r--]=0;Q[++r]=i; while(Q[h+1]-i>n)Q[++h]=0;if(i<=n) _min[i]=sum[i]-sum[Q[h+1]]; } Assert (~ (::Q)-p-sum[n+1] &1);intTemp= (::Q-p)-sum[n+1]>>1; for(i=1; i<=n;i++) {Long cost= (n-i+1)%n*y+ABS(temp)*x; _min[i]+=p+max (temp,0) * *;if(_min[i]<0) cost+= (1-_min[i]>>1)*x * *;if(Cost<ans) Ans=cost; } cout<<ans<<endl;return 0;}
Bzoj 1122 POI2008 ledger bbb monotone queue