zoukankan      html  css  js  c++  java
  • BZOJ2223/3524:[POI2014] Couriers(主席树)

    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行,每行对应一个答案。

    Sample Input

    7 5
    1 1 3 2 3 4 3
    1 3
    1 4
    3 7
    1 7
    6 6

    Sample Output

    1
    0
    3
    0
    4

    HINT

    【数据范围】

    n,m≤500000

    Solution

    就是递归查询区间sum是否大于(r-l+1)/2,是的话就递归左右儿子,否则return
    如果能一直递归到l==r就是有解,否则无解

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #define N (300000+100)
     6 using namespace std;
     7 struct node{int lson,rson,sum;}Segt[N*40];
     8 int a[N],b[N],n,m,Root[N],Segt_cnt,x,y,lim;
     9 
    10 int Build(int l,int r)
    11 {
    12     int node=++Segt_cnt;
    13     if (l==r) return node;
    14     int mid=(l+r)>>1;
    15     Segt[node].lson=Build(l,mid);
    16     Segt[node].rson=Build(mid+1,r);
    17     return node;
    18 }
    19 
    20 int Update(int pre,int l,int r,int x)
    21 {
    22     int node=++Segt_cnt;
    23     Segt[node].sum=Segt[pre].sum+1;
    24     Segt[node].lson=Segt[pre].lson;
    25     Segt[node].rson=Segt[pre].rson;
    26     if (l==r) return node;
    27     int mid=(l+r)>>1;
    28     if (x<=mid) Segt[node].lson=Update(Segt[node].lson,l,mid,x);
    29     else Segt[node].rson=Update(Segt[node].rson,mid+1,r,x);
    30     return node;
    31 }
    32 
    33 int Query(int u,int v,int l,int r)
    34 {
    35     int mid=(l+r)>>1,c=Segt[v].sum-Segt[u].sum;
    36     if (c<=(y-x+1)>>1) return 0;
    37     if (l==r) return b[l];    
    38     return max(Query(Segt[u].lson,Segt[v].lson,l,mid),Query(Segt[u].rson,Segt[v].rson,mid+1,r));
    39 }
    40 
    41 int main()
    42 {
    43     scanf("%d%d",&n,&lim);
    44     for (int i=1;i<=n;++i)
    45         scanf("%d",&a[i]),b[i]=a[i];
    46     sort(b+1,b+n+1);
    47     int num=unique(b+1,b+n+1)-b-1;
    48     Root[0]=Build(1,num);
    49     for (int i=1;i<=n;++i)
    50     {
    51         int t=lower_bound(b+1,b+num+1,a[i])-b;
    52         Root[i]=Update(Root[i-1],1,num,t);
    53     }
    54     scanf("%d",&m);
    55     for (int i=1;i<=m;++i)
    56     {
    57         scanf("%d%d",&x,&y);
    58         int ans=Query(Root[x-1],Root[y],1,num);
    59         if (ans) printf("yes %d
    ",ans);
    60         else printf("no
    ");
    61     }
    62 }
  • 相关阅读:
    [Leetcode]@python 65. Valid Number
    二维数组循环求出最大子数组
    一维循环的数组求出最大子数组的和
    电梯调度算法需求分析
    返回一个整数数组中最大子数组的和
    最大子数组求解
    小学数学计算题随机出题软件
    四则运算的设计思路
    学期读书计划
    软件工程概论第十一章
  • 原文地址:https://www.cnblogs.com/refun/p/8685685.html
Copyright © 2011-2022 走看看