由于算错了inf 又ak失败了 过于菜
T1 年轮蛋糕 loj 2758
题目大意:
n个数构成的环 把这个环分成三段 使最小的最大
求这个最小段的和的最大值
思路:
可以想到二分 因为log方可以过
所以可以二分长度后lower_bound找断点
或者使用滑动窗口
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 200100 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-')f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 ll n,g[MAXN],s[MAXN],l,r,mid,ans; 22 bool cheque(ll x) 23 { 24 ll a,b,c,ax,bx; 25 if(x>s[n]/2) return 0; 26 for(int i=1;i<=n;i++) 27 { 28 a=lower_bound(s+1,s+2*n+1,x+s[i-1])-s,ax=s[a]-s[i-1]; 29 if(a<n) b=lower_bound(s+1,s+2*n+1,ax+s[a])-s,bx=s[b]-s[a]; 30 else b=lower_bound(s+1,s+2*n+1,ax+s[a-n])-s,bx=s[b]-s[a-n]; 31 if(ax<=bx&&ax<=s[n]-ax-bx) return 1; 32 } 33 return 0; 34 } 35 int main() 36 { 37 n=read(); 38 for(int i=1;i<=n;i++) g[i]=read(),s[i]=s[i-1]+g[i]; 39 for(int i=n+1;i<=2*n;i++) s[i]=s[i-1]+g[i-n]; 40 r=s[n]; 41 while(l<=r) 42 { 43 mid=l+r>>1; 44 if(cheque(mid)) ans=mid,l=mid+1; 45 else r=mid-1; 46 } 47 printf("%lld",ans); 48 }