poj 3685 Matrix (二分套二分)

来源:互联网 发布:淘宝返利订单权重 编辑:程序博客网 时间:2024/06/15 08:19

题目链接:http://poj.org/problem?id=3685

题意:说的很明确了。

思路:

很经典的二分套二分,通过观察表达式我们可以发现当j一定的时候,原表达式的值是跟i相关并且是单调的,所以我们可以二分答案m,然后统计比m小的数有多少个,在统计的时候需要先枚举j,然后再二分i,统计完成后,还需要判断这个结果是否存在(即是否存在i,j使表达式的值等于m),为此我的做法是在统计<=m的数,如果<=m的数的个数大于<m的数则这个结果是存在的。

整个算法的复杂度是O(n*logn*longn) 这种二分再二分的思路是非常经典的~~~~。

code:

#include <cstdio>#include <cstdlib>#include <iostream>#define INF 10000005000using namespace std;typedef long long LL;LL N,M;LL cal(LL a,LL b){    return a*a+100000*a+b*b-100000*b+a*b;}bool judge(LL k){    LL res=0;    for(int j=1;j<=N;j++){        LL st=0,ed=N+1;        while(ed-st>1){            LL mid=(st+ed)/2;            if(cal(mid,j)>=k) ed=mid;            else st=mid;        }        res+=st;        if(res>=M) return true;    }    return false;}int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%lld%lld",&N,&M);        LL s=-(3*N*N+200000*N),t=3*N*N+200000*N;        while(t-s>1){            LL mid=(s+t)/2;            if(judge(mid)) t=mid;            else{                s=mid;            }        }        printf("%lld\n",s);    }    return 0;}


0 0
原创粉丝点击