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.