[atARC094D]Worst Case

首先,容易证明满足条件的$ip_{i}$必然是一个前缀

将其看成一张二分图,$i$向满足$ip_{i}<xy$的$p_{i}$连边,即找到一个前缀满足其有完美匹配

二分枚举前缀长度$k$,根据hall定理,即要求$\forall S\in [1,k],\lfloor\frac{xy-1}{\min_{i\in S}i}\rfloor\ge |S|$,很明显$S$是一个后缀时最难满足,换言之即要求$\forall 1\le i\le k,\lfloor\frac{xy-1}{i}\rfloor\ge k-i+1$($S=[i,k]$)

这又等价于$xy>ik-i^{2}+i$,后者是一个关于$i$的二次函数,求最大值即可判定

还有一个特殊的问题,左边的$x$和右边的$y$都不能被选入答案,换言之,即当$i\le x$,右式应为$k-i$;当$\lfloor\frac{xy-1}{\min_{i\in S}i}\rfloor\ge y$,左式(即该式)应为$\lfloor\frac{xy-1}{\min_{i\in S}i}\rfloor-1$

同时对于第二种情况,可以对$|S|$分类讨论,若$|S|<y$则减1无影响,若$|S|\ge y$则必然要减1(若该值小于$y$减1同样无影响),减1也可以看作对$|S|$加1,即$|S|\ge y$时可以加1

更具体的,对$i$作以下分类讨论:

1.对于$1\le i\le \min(x-1,k-y+1)$,求出$-i^{2}+(k+1)i$的最大值;

2.若$x\le k-y+1$,则对于$x<i\le k-y+1$,求出$-i^{2}+(k+2)i$的最大值;若$k-y+1<x$,则对于$k-y+1<i\le \min(x-1,k)$,求出$-i^{2}+ki$的最大值;

3.若$\max(x,k-y+1)<i\le k$,求出$-i^{2}+(k+1)i$的最大值

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define ll long long
 4 int t;
 5 ll x,y;
 6 ll get_mx(ll b,ll l,ll r){
 7     if (l>r)return 0;
 8     if (b%2==0){
 9         if ((l<=b/2)&&(b/2<=r))return b*b/4;
10         return max((b-l)*l,(b-r)*r);
11     }
12     if ((l<=b/2)&&(b/2<=r)||(l<=b/2+1)&&(b/2+1<=r))return (b/2)*(b/2+1);
13     return max((b-l)*l,(b-r)*r);
14 }
15 bool pd(ll k){
16     if (get_mx(k+1,1,min(x-1,k-y+1))>=x*y)return 0;
17     if (get_mx(k+2,x+1,k-y+1)>=x*y)return 0;
18     if (get_mx(k,k-y+2,min(x-1,k))>=x*y)return 0;
19     if (get_mx(k+1,max(x,k-y+1)+1,k)>=x*y)return 0;
20     return 1;
21 }
22 int main(){
23     scanf("%d",&t);
24     while (t--){
25         scanf("%lld%lld",&x,&y);
26         if (x>y)swap(x,y);
27         ll l=0,r=2e9;
28         while (l<r){
29             ll mid=(l+r+1>>1);
30             if (pd(mid))l=mid;
31             else r=mid-1;
32         }
33         printf("%lld\n",l-(l>=x));
34     }
35 } 
View Code

 

posted @ 2020-11-29 18:33  PYWBKTDA  阅读(162)  评论(0编辑  收藏  举报