zoukankan      html  css  js  c++  java
  • 一道二分的题

    对于一个长度为n的序列和一个长度为m的序列,它们之间任意两个数的乘积构成了一个长度为n*m的新序列,n和m的范围为10^5,这m*n的范围是10^10,

    问新序列中第k大的数是少,

    对于这样一个问题,由于范围太大且数组开不下,所以不能采取常规的排序或者树状数组来做,那么剩下想到的只有二分了。

    首先将长度为n的a序列和长度为m的b序列分别排序,如果从小到大排序,那么新序列的范围就是a[0]*b[0]~~a[n-1]*b[m-1],然后在这个范围内二分每次

    找寻中间值mid,每找到一次就枚举a数列依次然后二分b数列,找到乘积不大于mid的个数然后与k比较,若小于k,则说明mid小了,继续往右边二分不然就是

    mid大了然后往左边二分。就是二分次数,讲的不清楚具体看代码吧。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <iostream>
     4 using namespace std;
     5 const int M=1e5+10;
     6 typedef long long ll;
     7 ll a[M],b[M];
     8 
     9 int main() {
    10     int n,m,i;ll k;
    11     while(~scanf("%d%d%I64d",&n,&m,&k)){
    12         for(i=0;i<n;i++) scanf("%I64d",&a[i]);
    13         for(i=0;i<m;i++) scanf("%I64d",&b[i]);
    14         sort(a,a+n);
    15         sort(b,b+m);
    16         k=(ll)n*m-k+1;
    17         ll maxMul=a[n-1]*b[m-1];
    18         ll l=a[0]*b[0],r=maxMul,mid,cnt,answer = 0;
    19         while (l <= r) {
    20             mid = l + r >> 1;
    21             cnt = 0;
    22             for(int i = 0; i < n; ++i) {
    23                 int sl = 0, sr = m - 1, smid, scnt = 0;
    24                 for(; sl <= sr;) {
    25                     smid = sl + sr >> 1;
    26                     if(a[i]*b[smid] > mid) sr = smid - 1;
    27                     else scnt = smid + 1, sl = smid + 1;
    28                 }
    29                 cnt += scnt;
    30             }
    31             if(cnt < k) {
    32                 l = mid + 1;
    33             } else {
    34                 r = mid - 1;
    35                 answer = mid;
    36             }
    37         }
    38         printf("%I64d
    ", answer);
    39     }
    40     return 0;
    41 }
  • 相关阅读:
    P1032 字串变换
    P3203 [HNOI2010]弹飞绵羊
    P3690 【模板】Link Cut Tree (动态树)
    P2147 [SDOI2008]洞穴勘测
    P3950 部落冲突
    Codeforces Round #469 Div. 2题解
    线段树
    SDOI2018退役记
    4.1模拟题
    无旋Treap
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/5313335.html
Copyright © 2011-2022 走看看