CodeForces 650B Image Preview
直接走,或者回一次头反向走。
预处理前缀费用,反向的时候 二分查找一下。
WA点:注意一开始就可以往左。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=5e5+10; int n; long long a,b; long long T; long long sum1[maxn],sum2[maxn]; char s[maxn],e[maxn]; int ans1,ans2; int main() { scanf("%d",&n); scanf("%lld%lld%lld",&a,&b,&T); memset(s,0,sizeof s); scanf("%s",s); int len=strlen(s); memset(sum1,0,sizeof sum1); memset(sum2,0,sizeof sum2); ans1=0; if(s[0]=='w') sum1[1]=1+b; else sum1[1]=1; if(sum1[1]<=T) ans1=1; for(int i=1;s[i];i++) { if(s[i]=='h') sum1[i+1]=sum1[i]+a+1; else sum1[i+1]=sum1[i]+a+b+1; if(sum1[i+1]<=T) ans1=i+1; } int tot=2; if(s[len-1]=='w') sum2[1]=1+b; else sum2[1]=1; if(sum2[1]<=T) ans2=1; for(int i=len-2;i>=0;i--) { if(s[i]=='h') sum2[tot]=sum2[tot-1]+a+1; else sum2[tot]=sum2[tot-1]+a+b+1; tot++; } for(int i=1;i<=n;i++) { long long ff=(long long)i; if(sum1[i]+ff*a>T) continue; else if(sum1[i]+ff*a<T) { int tmp=i; long long v=T-(sum1[i]+ff*a); int pos=-1; int l=1,r=n-i; int mid; while(l<=r) { mid=(l+r)/2; if(sum2[mid]<=v) { pos=mid; l=mid+1; } else r=mid-1; } if(pos!=-1) tmp=tmp+pos; ans1=max(ans1,tmp); } } memset(e,0,sizeof e); e[0]=s[0]; int y=1; for(int i=len-1;i>=1;i--) e[y++]=s[i]; strcpy(s,e); memset(sum1,0,sizeof sum1); memset(sum2,0,sizeof sum2); ans2=0; if(s[0]=='w') sum1[1]=1+b; else sum1[1]=1; for(int i=1;s[i];i++) { if(s[i]=='h') sum1[i+1]=sum1[i]+a+1; else sum1[i+1]=sum1[i]+a+b+1; if(sum1[i+1]<=T) ans2=i+1; } tot=2; if(s[len-1]=='w') sum2[1]=1+b; else sum2[1]=1; for(int i=len-2;i>=0;i--) { if(s[i]=='h') sum2[tot]=sum2[tot-1]+a+1; else sum2[tot]=sum2[tot-1]+a+b+1; tot++; } for(int i=1;i<=n;i++) { long long ff=(long long)i; if(sum1[i]+ff*a>T) continue; else if(sum1[i]+ff*a<T) { int tmp=i; long long v=T-(sum1[i]+ff*a); int pos=-1; int l=1,r=n-i; int mid; while(l<=r) { mid=(l+r)/2; if(sum2[mid]<=v) { pos=mid; l=mid+1; } else r=mid-1; } if(pos!=-1) tmp=tmp+pos; ans2=max(ans2,tmp); } } printf("%d\n",max(ans1,ans2)); return 0; }