• 【主席树】bzoj3524: [Poi2014]Couriers


    主席树 上 二分(和线段树上二分一个道理的单支log

    Description

    给一个长度为n的序列a。1≤a[i]≤n。
    m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2。如果存在,输出这个数,否则输出0。

    Input

    第一行两个数n,m。
    第二行n个数,a[i]。
    接下来m行,每行两个数l,r,表示询问[l,r]这个区间。

    Output

    m行,每行对应一个答案。


    题目分析

    线段树 上 二分的一个简单应用。

    有些时候就是把套二分做成上二分,少一只log

     1 #include<bits/stdc++.h>
     2 const int maxn = 500035;
     3 const int maxNode = 12000035;
     4 
     5 struct node
     6 {
     7     int val,l,r;
     8 }a[maxNode];
     9 int n,m,tot,rt[maxn],w[maxn],cnt[maxn];
    10 
    11 int read()
    12 {
    13     char ch = getchar();
    14     int num = 0, fl = 1;
    15     for (; !isdigit(ch); ch=getchar())
    16         if (ch=='-') fl = -1;
    17     for (; isdigit(ch); ch=getchar())
    18         num = (num<<1)+(num<<3)+ch-48;
    19     return num*fl;
    20 }
    21 void build(int &rt, int l, int r)
    22 {
    23     rt = ++tot;
    24     if (l==r) return;
    25     int mid = (l+r)>>1;
    26     build(a[rt].l, l, mid);
    27     build(a[rt].r, mid+1, r);
    28 }
    29 void update(int pre, int &rt, int l, int r, int c)
    30 {
    31     rt = ++tot, a[rt] = a[pre], ++a[rt].val;
    32     if (l==r) return;
    33     int mid = (l+r)>>1;
    34     if (c <= mid) update(a[pre].l, a[rt].l, l, mid, c);
    35     else update(a[pre].r, a[rt].r, mid+1, r, c);
    36 }
    37 int query(int L, int R)
    38 {
    39     int l = 1, r = cnt[0], x = rt[L-1], y = rt[R], lim = (R-L+1)>>1, mid;
    40     while (l!=r)
    41     {
    42         mid = (l+r)>>1;
    43         if (a[y].val-a[x].val <= lim) return 0;
    44         if (a[a[y].l].val-a[a[x].l].val > lim)
    45             r = mid, x = a[x].l, y = a[y].l;
    46         else if (a[a[y].r].val-a[a[x].r].val > lim)
    47             l = mid+1, x = a[x].r, y = a[y].r;
    48         else return 0;
    49     }
    50     return cnt[l];
    51 }
    52 void write(int x){if (x/10) write(x/10);putchar(x%10+'0');}
    53 int main()
    54 {
    55     n = read(), m = read();
    56     for (int i=1; i<=n; i++) cnt[i] = w[i] = read();
    57     std::sort(cnt+1, cnt+n+1);
    58     cnt[0] = std::unique(cnt+1, cnt+n+1)-cnt-1;
    59     build(rt[0], 1, n);
    60     for (int i=1; i<=n; i++)
    61     {
    62         w[i] = std::lower_bound(cnt+1, cnt+cnt[0]+1, w[i])-cnt;
    63         update(rt[i-1], rt[i], 1, cnt[0], w[i]);
    64     }
    65     for (int i=1; i<=m; i++)
    66     {
    67         int l = read(), r = read();
    68         write(query(l, r)), putchar('
    ');
    69     }
    70     return 0;
    71 }

    END

  • 相关阅读:
    转自苦大师:移动测试Appium之API手册
    怨念与发飙
    Asp.Net 2.0新特性
    汉字是最优美的文字
    加入cnblog留念
    Thrift之TProtocol类体系原理及源码详细解析之其他协议类和总结
    Thrift之TProtocol类体系原理及源码详细解析之二进制协议类TBinaryProtocolT(TBinaryProtocol)
    linux内核bug问题排查过程详细报告
    Thrift之TProtocol类体系原理及源码详细解析之紧凑协议类TCompactProtocolT(TCompactProtocol)
    Thrift之TProcess类体系原理及源码详细解析
  • 原文地址:https://www.cnblogs.com/antiquality/p/10251612.html
Copyright © 2020-2023  润新知