首页 > 代码库 > P1894セチの祈り
P1894セチの祈り
描述
在 Ninian 的花园里,有许多琼花,环绕着中间的凉亭。
有 N 片琼花,组成一个环。
Ninian 想在凉亭中发动 [セチの祈り] , 需要划分出三个区域的琼花,为了平均,要最大化面积最小的区域的面积。
划分区域:即用三刀把这个环分成三段,每段称之为一个区域。
题解:
就会这一题写一下题解吧。。。
如果不是环形的话,显然二分+O(n)判断就可以,因为满足单调性。
如果是环形,我们需要枚举起点,所以复杂度成了n*n*logn
但是我们考虑优化判断的时间复杂度,因为a是一个单调递增的数组,所以我们照样可以lower_bound下一段>当前二分值的区间。复杂度变为n*log2n
代码:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<iostream> 7 #include<vector> 8 #include<map> 9 #include<set>10 #include<queue>11 #include<string>12 #define inf 100000000013 #define maxn 200000+10014 #define maxm 500+10015 #define eps 1e-1016 #define ll long long17 #define pa pair<int,int>18 #define for0(i,n) for(int i=0;i<=(n);i++)19 #define for1(i,n) for(int i=1;i<=(n);i++)20 #define for2(i,x,y) for(int i=(x);i<=(y);i++)21 #define for3(i,x,y) for(int i=(x);i>=(y);i--)22 #define mod 100000000723 using namespace std;24 inline ll read()25 {26 ll x=0,f=1;char ch=getchar();27 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}28 while(ch>=‘0‘&&ch<=‘9‘){x=10*x+ch-‘0‘;ch=getchar();}29 return x*f;30 }31 int n;32 ll a[2*maxn];33 inline bool check(ll x,int y)34 {35 int xx=lower_bound(a+y,a+y+n,a[y-1]+x)-a;36 if(xx>=y+n)return 0;37 int yy=lower_bound(a+xx+1,a+y+n,a[xx]+x)-a;38 if(yy>=y+n)return 0;39 return a[n+y-1]-a[yy]>=x;40 }41 int main()42 {43 freopen("input.txt","r",stdin);44 freopen("output.txt","w",stdout);45 n=read();ll sum=0;46 for1(i,n)a[i]=a[n+i]=read(),sum+=a[i];47 for1(i,n<<1)a[i]+=a[i-1];48 ll ans=0;49 for1(i,n)50 {51 if(!check(ans,i))continue;52 ll l=ans,r=sum,mid;53 while(l<=r)54 {55 mid=(l+r)>>1;56 if(!check(mid,i))r=mid-1;else l=mid+1;57 }58 ans=max(ans,r);59 }60 printf("%lld\n",ans);61 return 0;62 }
P1894セチの祈り
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。