5185. 【NOIP2017提高组模拟6.30】tty's sequence (Standard IO)
Description
Input
Output
Solution
显然:
最大的二进制或值是选n个,因为不会变小;
最大的二进制与值是选k个,因为不会变大。
所以或值可以很容易的得到,for一遍即可,O(n)
而与值,则需开线段树维护区间,查询只需O(logn),总得需O(nlogn)
代码
1 type 2 arr=record 3 l,r,w:longint; 4 end; 5 var 6 n,k,ans1,ans2,num:longint; 7 a:array [0..1000001] of longint; 8 tree:array [0..4000001] of arr; 9 function max(o,p:longint):longint; 10 begin 11 if o>p then exit(o); 12 exit(p); 13 end; 14 15 procedure init; 16 var 17 i:longint; 18 begin 19 readln(n,k); 20 ans1:=0; 21 for i:=1 to n do 22 begin 23 read(a[i]); 24 ans1:=ans1 or a[i]; 25 end; 26 end; 27 28 procedure build(p,l,r:longint); 29 var 30 mid:longint; 31 begin 32 if l=r then 33 begin 34 tree[p].w:=a[l]; 35 exit; 36 end; 37 mid:=(l+r) div 2; 38 build(p*2,l,mid); 39 build(p*2+1,mid+1,r); 40 tree[p].w:=tree[p*2].w and tree[p*2+1].w; 41 end; 42 43 procedure find(p,l,r,x,y:longint); 44 var 45 mid:longint; 46 begin 47 if (l=x) and (r=y) then 48 begin 49 num:=num and tree[p].w; 50 exit; 51 end; 52 mid:=(l+r) div 2; 53 if y<=mid then find(p*2,l,mid,x,y) else 54 if x>mid then find(p*2+1,mid+1,r,x,y) else 55 begin 56 find(p*2,l,mid,x,mid); 57 find(p*2+1,mid+1,r,mid+1,y); 58 end; 59 end; 60 61 procedure main; 62 var 63 i,m:longint; 64 begin 65 ans2:=0; m:=n-k+1; 66 for i:=1 to m do 67 begin 68 num:=maxlongint; 69 find(1,1,n,i,i+k-1); 70 ans2:=max(ans2,num); 71 end; 72 end; 73 74 begin 75 init; 76 build(1,1,n); 77 main; 78 writeln(ans1,' ',ans2); 79 end.