zoukankan      html  css  js  c++  java
  • C++之路进阶——bzoj3524(Couriers)

    F.A.QsHomeDiscussProblemSetStatusRanklistContestModifyUser   gryz2016Logout捐赠本站
    Notice:由于本OJ建立在Linux平台下,而许多题的数据在Windows下制作,请注意输入、输出语句及数据类型及范围,避免无谓的RE出现。

    3524: [Poi2014]Couriers

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 1058  Solved: 363
    [Submit][Status][Discuss]

    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


    Source

    代码:

       

     1 #include<cstdio>
     2 #include<iostream>
     3  
     4 using namespace std;
     5  
     6 int n,m,sz;
     7 int root[500010],ls[10000010],rs[10000010],sum[10000010];
     8  
     9 void update(int l,int r,int x,int &y,int v)
    10 {
    11     y=++sz;
    12     sum[y]=sum[x]+1;
    13     if(l==r)return;
    14     ls[y]=ls[x];
    15     rs[y]=rs[x];
    16     int mid=(l+r)>>1;
    17     if(v<=mid) update(l,mid,ls[x],ls[y],v);
    18     else update(mid+1,r,rs[x],rs[y],v);
    19 }
    20  
    21 int que(int L,int R)
    22  {
    23     int l=1,r=n,mid,x,y,tmp=(R-L+1)>>1;
    24     x=root[L-1];y=root[R];
    25     while(l!=r)
    26     {
    27         if(sum[y]-sum[x]<=tmp)return 0;
    28         mid=(l+r)>>1;
    29         if(sum[ls[y]]-sum[ls[x]]>tmp)
    30          {
    31            r=mid;
    32            x=ls[x];
    33            y=ls[y];
    34           } else
    35         if(sum[rs[y]]-sum[rs[x]]>tmp)
    36         {
    37            l=mid+1;
    38            x=rs[x];
    39            y=rs[y];
    40         }
    41         else return 0;
    42     }
    43     return l;
    44  }
    45  
    46 int main()
    47 {
    48     scanf("%d%d",&n,&m);
    49     for(int i=1;i<=n;i++)
    50     {
    51         int x;
    52         scanf("%d",&x);
    53         update(1,n,root[i-1],root[i],x);
    54     }
    55     for(int i=1;i<=m;i++)
    56     {
    57         int l,r;
    58         scanf("%d%d",&l,&r);
    59         printf("%d
    ",que(l,r));
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    Qt学习之路,part1
    1.获取状态栏的高度
    如何在Android Studio中上传代码到Gitee上
    关于类图
    外观模式
    关于类的实例
    SharedPreference中关于editor.apply()和editor.commit()
    活动的4种启动模式
    unittest中case批量管理
    unittest使用
  • 原文地址:https://www.cnblogs.com/grhyxzc/p/5144184.html
Copyright © 2011-2022 走看看