zoukankan      html  css  js  c++  java
  • 【BZOJ3524】Couriers(主席树)

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

    n,m≤500000


    思路:这题可以用主席树巧妙地做

    询问(x,y)区间时直接输出a[query(x,y)]

    首先区间内个数>(r-l+1)/2的数字如果有的话有且只有一个

    其次答案数字肯定在数字总和大于一半的一边

    这样询问可以做到logn

    离散化注意

     1 var t:array[0..20000000]of record
     2                             l,r,s:longint;
     3                            end;
     4     a,b,c,d,root,h:array[0..1000000]of longint;
     5     n,m,i,x,y,cnt:longint;
     6 
     7 procedure swap(var x,y:longint);
     8 var t:longint;
     9 begin
    10  t:=x; x:=y; y:=t;
    11 end;
    12 
    13 procedure qsort(l,r:longint);
    14 var i,j,mid:longint;
    15 begin
    16  i:=l; j:=r; mid:=a[(l+r)>>1];
    17  repeat
    18   while mid>a[i] do inc(i);
    19   while mid<a[j] do dec(j);
    20   if i<=j then
    21   begin
    22    swap(a[i],a[j]);
    23    swap(c[i],c[j]);
    24    inc(i); dec(j);
    25   end;
    26  until i>j;
    27  if l<j then qsort(l,j);
    28  if i<r then qsort(i,r);
    29 end;
    30 
    31 procedure update(l,r:longint;var p:longint;x:longint);
    32 var mid:longint;
    33 begin
    34  inc(cnt); t[cnt]:=t[p];
    35  p:=cnt; inc(t[p].s);
    36  if l=r then exit;
    37  mid:=(l+r)>>1;
    38  if x<=mid then update(l,mid,t[p].l,x)
    39   else update(mid+1,r,t[p].r,x);
    40 end;
    41 
    42 function query(p1,p2,l,r,k:longint):longint;
    43 var mid,t1,t2:longint;
    44 begin
    45  if l=r then exit(l);
    46  t1:=t[t[p2].l].s-t[t[p1].l].s;
    47  t2:=t[t[p2].r].s-t[t[p1].r].s;
    48  mid:=(l+r)>>1;
    49  if t1>=k then exit(query(t[p1].l,t[p2].l,l,mid,k))
    50   else if t2>=k then exit(query(t[p1].r,t[p2].r,mid+1,r,k))
    51    else exit(0);
    52 end;
    53 
    54 begin
    55  assign(input,'bzoj3524.in'); reset(input);
    56  assign(output,'bzoj3524.out'); rewrite(output);
    57  readln(n,m);
    58  for i:=1 to n do
    59  begin
    60   read(a[i]);
    61   b[i]:=a[i]; c[i]:=i;
    62  end;
    63  qsort(1,n);
    64  d[c[1]]:=1;
    65  for i:=2 to n do
    66   if a[i]<>a[i-1] then d[c[i]]:=d[c[i-1]]+1
    67    else d[c[i]]:=d[c[i-1]];  //离散化
    68  for i:=1 to n do h[d[i]]:=b[i]; //离散化后还原原数
    69  for i:=1 to n do
    70  begin
    71   root[i]:=root[i-1];
    72   update(1,n,root[i],d[i]);
    73  end;
    74  for i:=1 to m do
    75  begin
    76   readln(x,y);
    77   writeln(h[query(root[x-1],root[y],1,n,(y-x+1) div 2+1)]);
    78  end;
    79  close(input);
    80  close(output);
    81 end.
  • 相关阅读:
    WPF 本地化语言设置
    WPF 调节树状图滚动条值
    WPF中ListBox的使用注意事项
    SQL 树状结构表中查出所所有父级/子级
    Vue创建
    wpf 控件注意事项
    链表习题(1)-设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点
    排序-快速排序
    排序-堆排序
    图-图的遍历
  • 原文地址:https://www.cnblogs.com/myx12345/p/6131741.html
Copyright © 2011-2022 走看看