zoukankan      html  css  js  c++  java
  • [POJ2104] K-th Number(归并树,二分)

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

    题意:略

    最近想学一下分块,搜到了这道题。结果在《挑战》上另外看到了另外的用线段树做的算法。后来才知道,这种记录归并排序过程的树叫归并树。利用STL,非常好实现。

    思路就是首先二分答案,拿着这个答案在归并树上找对应区间比这个数小的数的个数ret,找到==k的为止。

    稍微对拍后,重新划了一下query的区间才发现是第40行写搓了。最近不刷题,码力下降了啊。。

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <iomanip>
     4 #include <cstring>
     5 #include <climits>
     6 #include <complex>
     7 #include <cassert>
     8 #include <cstdio>
     9 #include <bitset>
    10 #include <vector>
    11 #include <deque>
    12 #include <queue>
    13 #include <stack>
    14 #include <ctime>
    15 #include <set>
    16 #include <map>
    17 #include <cmath>
    18 using namespace std;
    19 
    20 #define lrt rt << 1
    21 #define rrt rt << 1 | 1
    22 const int maxn = 100100;
    23 int n, q, a[maxn];
    24 vector<int> seg[maxn<<2];
    25 
    26 void build(int l, int r, int rt) {
    27     if(l == r) {
    28         seg[rt].clear();
    29         seg[rt].push_back(a[l]);
    30         return;
    31     }
    32     int mid = (l + r) >> 1;
    33     build(l, mid, lrt);
    34     build(mid+1, r, rrt);
    35     seg[rt].resize(r-l+1);
    36     merge(seg[lrt].begin(), seg[lrt].end(), seg[rrt].begin(), seg[rrt].end(), seg[rt].begin());
    37 }
    38 
    39 int query(int L, int R, int v, int l, int r, int rt) {
    40     if(R < l || r < L) return 0;
    41     if(L <= l && r <= R) return upper_bound(seg[rt].begin(), seg[rt].end(), v) - seg[rt].begin();
    42     int mid = (l + r) >> 1;
    43     return query(L, R, v, l, mid, lrt) + query(L, R, v, mid+1, r, rrt);
    44 }
    45 
    46 inline bool scan_d(int &num) {
    47     char in;bool IsN=false;
    48     in=getchar();
    49     if(in==EOF) return false;
    50     while(in!='-'&&(in<'0'||in>'9')) in=getchar();
    51     if(in=='-'){ IsN=true;num=0;}
    52     else num=in-'0';
    53     while(in=getchar(),in>='0'&&in<='9'){
    54         num*=10,num+=in-'0';
    55     }
    56     if(IsN) num=-num;
    57     return true;
    58 }
    59 
    60 inline void out(int x) { 
    61     if (x > 9) out(x / 10); 
    62     putchar(x % 10 + '0');
    63 }
    64 
    65 int main() {
    66     // freopen("in", "r", stdin);
    67     // freopen("out", "w", stdout);
    68     int T, l, r, k;
    69     while(scan_d(n)) {
    70         scan_d(q);
    71         for(int i = 1; i <= n; i++) scan_d(a[i]);
    72         build(1, n, 1);
    73         sort(a+1, a+n+1);
    74         while(q--) {
    75             scan_d(l); scan_d(r); scan_d(k);
    76             int lo = 1, hi = n;
    77             int v;
    78             while(lo <= hi) {
    79                 int mid = (lo + hi) >> 1;
    80                 int ret = query(l, r, a[mid], 1, n, 1);
    81                 if(ret >= k) {
    82                     hi = mid - 1;
    83                     v = a[mid];
    84                 }
    85                 else lo = mid + 1;
    86             }
    87             printf("%d
    ", v);
    88         }
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    python3 基本使用多线程
    img前置显示屏装load图片
    leetcode
    亲串 (hdu 2203 KMP)
    基于VC面部识别软件(识别出人脸特征)
    IT该忍者神龟Oracle 树操作(select…start with…connect by…prior)
    It&#39;s about trust
    hdu 2128 Frog(简单DP)
    第四十天 阿乐在其中—Android小游戏的飞机(四)加入敌人
    Mac OS X通过结合80port
  • 原文地址:https://www.cnblogs.com/kirai/p/6925950.html
Copyright © 2011-2022 走看看