pku3368 Frequent values

有一个长度为n(n<=100000)的有序序列,对于Q(Q<=100000)条询问(x,y)输出区间[x,y]中出现次数最多的数的次数。

用maxl表示包括左端点的最长重复数的个数

maxr表示包括右端点的最长重复数的个数

sum表示在该区间内重复数的最大个数,

那么就很容易建立线段树,由儿子节点去求父亲节点,具体的规划式在程序里很清楚。

View Code
  1 program pku3368(input,output);
  2 type
  3    node    = record
  4          left,right,x,y,maxl,maxr,sum : longint;
  5       end;
  6 var
  7    tree       : array[0..300000] of node;
  8    a       : array[0..100010] of longint;
  9    n,q,tot : longint;
 10 function max(aa,bb: longint):longint;
 11 begin
 12    if aa>bb then
 13       exit(aa);
 14    exit(bb);
 15 end; { max }
 16 function min(aa,bb :longint ): longint;
 17 begin
 18    if aa<bb then
 19       exit(aa);
 20    exit(bb);
 21 end; { min }
 22 procedure build(xx,yy :longint );
 23 var
 24    now,mid : longint;
 25 begin
 26    inc(tot);
 27    now:=tot;
 28    tree[now].x:=xx;
 29    tree[now].y:=yy;
 30    if xx=yy then
 31    begin
 32       tree[now].maxl:=1;
 33       tree[now].maxr:=1;
 34       tree[now].sum:=1;
 35       exit;
 36    end;
 37    mid:=(xx+yy)>>1;
 38    tree[now].left:=tot+1;
 39    build(xx,mid);
 40    tree[now].right:=tot+1;
 41    build(mid+1,yy);
 42    if a[tree[tree[now].left].x]=a[tree[tree[now].right].x] then
 43       tree[now].maxl:=(mid-xx+1)+tree[tree[now].right].maxl
 44    else
 45       tree[now].maxl:=tree[tree[now].left].maxl;
 46    if a[tree[tree[now].left].y]=a[tree[tree[now].right].y] then
 47       tree[now].maxr:=(yy-mid)+tree[tree[now].left].maxr
 48    else
 49       tree[now].maxr:=tree[tree[now].right].maxr;
 50    tree[now].sum:=max(tree[tree[now].left].sum,tree[tree[now].right].sum);
 51    if a[tree[tree[now].left].y]=a[tree[tree[now].right].x] then
 52       tree[now].sum:=max(tree[now].sum,tree[tree[now].left].maxr+tree[tree[now].right].maxl);
 53    tree[now].sum:=max(tree[now].sum,tree[now].maxl);
 54    tree[now].sum:=max(tree[now].sum,tree[now].maxr);
 55 end; { build }
 56 procedure init;
 57 var
 58    i : longint;
 59 begin
 60    tot:=0;
 61    readln(q);
 62    for i:=1 to n do
 63       read(a[i]);
 64    readln;
 65    build(1,n);
 66 end; { init }
 67 function getans(now,xx,yy :longint ):longint;
 68 var
 69    mid : longint;
 70    tmp : longint;
 71 begin
 72    tmp:=0;
 73    if (tree[now].x=xx)and(tree[now].y=yy) then
 74       exit(tree[now].sum);
 75    mid:=(tree[now].x+tree[now].y)>>1;
 76    if yy<=mid then
 77       exit(getans(tree[now].left,xx,yy))
 78    else
 79       if xx>mid then
 80      exit(getans(tree[now].right,xx,yy))
 81       else
 82       begin
 83      if a[mid]=a[mid+1] then
 84         tmp:=min((mid-xx+1),tree[tree[now].left].maxr)+min((yy-mid),tree[tree[now].right].maxl);
 85      tmp:=max(tmp,getans(tree[now].left,xx,mid));
 86      tmp:=max(tmp,getans(tree[now].right,mid+1,yy));
 87      exit(tmp);
 88       end;
 89 end; { getans }
 90 procedure solve();
 91 var
 92    i,x,y : longint;
 93 begin
 94    for i:=1 to q do
 95    begin
 96       readln(x,y);
 97       writeln(getans(1,x,y));
 98    end;
 99 end; { solve }
100 begin
101    read(n);
102    while n<>0 do
103    begin
104       init;
105       solve;
106       read(n);
107    end;
108 end.
posted @ 2012-04-14 10:37  Codinginging  阅读(207)  评论(0编辑  收藏  举报