zoukankan      html  css  js  c++  java
  • zoj 3278 8G Island(二分)

    题意:给出n个元素的数组a和m个元素的数组b,求数组a中元素与数组b中元素相乘所得乘积的第k大值;

    思路:暴力超时,采用二分;先将两数组从大到小排序,外层二分枚举答案,内层二分查找与当前枚举值相等的乘积所在的区间;

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    typedef long long ll;
    #define inf 100000000010
    using namespace std;
    ll kth,n,m;
    ll a[500010],b[500010];
    int cmp(int a1,int b1)
    {
        return a1>b1;
    }
    int main()
    {
        int k,i,j;
        while(scanf("%lld%lld%lld",&n,&m,&kth)!=EOF)
        {
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            for(i=1;i<=n;i++) scanf("%lld",&a[i]);
            for(i=1;i<=m;i++) scanf("%lld",&b[i]);
            sort(a+1,a+n+1,cmp);
            sort(b+1,b+m+1,cmp);
            b[0]=inf;b[m+1]=-1;
            ll Min=a[n]*b[m];
            ll Max=a[1]*b[1];
            ll Low=Min;
            ll High=Max;
            ll ans=Max;
            while(Low<=High)
            {
                ll Mid=(Low+High)/2;
                ll key=Mid;
                ll s1=0,s2=0;
                for(i=1;i<=n;i++)
                {
                    int low,high,res;
                    ll val=a[i]*b[1];
                    ll val2=a[i]*b[m];
                    if(val2>key)
                    {
                        s1+=m;
                        continue;
                    }
                    if(val<key)
                    {
                        s2+=m;
                        continue;
                    }
                    low=1,high=m,res=0;
                    while(low<=high)
                    {
                        int mid=(low+high)/2;
                        val=a[i]*b[mid];
                        val2=a[i]*b[mid+1];
                        if(val>key&&val2<=key)
                        {
                            res=mid;
                            break;
                        }
                        else if(val2>key)
                            low=mid+1;
                        else
                            high=mid-1;
                    }
                    s1+=res;
                    low=1,high=m,res=m+1;
                    while(low<=high)
                    {
                        int mid=(low+high)/2;
                        val=a[i]*b[mid];
                        val2=a[i]*b[mid-1];
                        if(val<key&&val2>=key)
                        {
                            res=mid;break;
                        }
                        else if(val2<key)
                        {
                            high=mid-1;
                        }
                        else
                            low=mid+1;
                    }
                    s2+=(m-res+1);
                }
                ll left=s1+1;
                ll right=n*m-s2;
                if(left<=kth&&kth<=right)
                {
                    ans=key;break;
                }
                else if(kth<left)
                {
                    Low=Mid+1;
                }
                else High=Mid-1;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    servlet异步处理机制
    分析logfilter+session
    java web后台工作原理
    xml的作用
    本学期学习目标 企业级运用和互联网运用的区别
    JAVA EE 思维导图
    第六周
    第五周
    第四周作业
    javaee第三周
  • 原文地址:https://www.cnblogs.com/dashuzhilin/p/4574906.html
Copyright © 2011-2022 走看看