Atcoder 700 Worst Case 貪心+二分
阿新 • • 發佈:2018-11-02
題意:兩個1,2,3,....inf的集合A,B. 從兩個集合中各選一個數(a,b)的得分為a*b.
Q次詢問,每次詢問(a,b),[表示分別選中a,b].問從剩下的兩個集合中最多能選出多少對(x,y)使得x*y<a*b
Q<=100. 1<=a,b<=1e9.
當a<b
1,2,3,....a-1,a,a+1.....
1,2,3..C.............b,b+1......
(a+1)*(b+1)>ab , a<b時 (a-i)*(b+i)=ab+ai-bi-i*i < ab 所以讓[1..a-1]和[b+1...]匹配.
[a+1..]這部分顯然只能在b之前匹配 並且也是第i小的第i大匹配.
二分一個c 要找到 max(i*(a+c-i+1))[i=1..c] 中的最大值是否<ab
因為是二次函式 在極點附近列舉一下即可.
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+5; ll Q,a,b; bool check(ll c) { //f[x]=-x^2+(a+c+1)*x ll A=-1,B=(a+c+1); ll po=-B/(2ll*A); //cout<<po<<'\n'; for(ll i=max(1ll,po-500);i<=min(c,po+500);i++) { if(i*(a+c-i+1)>=a*b) return false; } return true; } int main() { cin>>Q; while(Q--) { cin>>a>>b; if(a>b) swap(a,b); ll l=1,r=b,p; while(l<=r) { ll mid=l+r>>1; if(check(mid)) l=mid+1,p=mid; else r=mid-1; } ll res=a-1+p; cout<<res<<'\n'; } return 0; }