您的位置:首页 > 其它

【BZOJ4199&UOJ131】品酒大会(后缀数组,并查集)

2017-04-14 11:40 435 查看

题意:

 

两杯“r相似” (r>1)的酒同时也是“1 相似”、“2 相似”、……、“(r−1) 相似”的。

n<=300000 abs(a[i])<=10^9

思路:对于i,j两个后缀,它们的贡献只与它们的lcp有关

而lcp又是它们之间height的最小值

所以可以把height从大到小排序

然后用并查集合并最值,方案数之类的

每次合并的都是排名相邻的一对后缀,相当于一段不相交的线段

每个集合中的lcp即为height的最小值

将r相似的加到r-1相似中

被UOJ的extra卡了一发,原来是0相似的初始最大值忘记初始化了

1 const oo=1<<62;
2 var sum,f:array[0..310000]of int64;
3     sa,rank,height,id,mx,mn,size,a,fa,x,y,wc,wd,b:array[0..310000]of longint;
4     n,m,i,p,q,t:longint;
5     ch:ansistring;
6 procedure swap(var x,y:longint);
7 var t:longint;
8 begin
9  t:=x; x:=y; y:=t;
10 end;
11
12 function max(x,y:int64):int64;
13 begin
14  if x>y then exit(x);
15  exit(y);
16 end;
17
18 function min(x,y:longint):longint;
19 begin
20  if x<y then exit(x);
21  exit(y);
22 end;
23
24 procedure qsort(l,r:longint);
25 var i,j,mid:longint;
26 begin
27  i:=l; j:=r; mid:=height[id[(l+r)>>1]];
28  repeat
29   while mid<height[id[i]] do inc(i);
30   while mid>height[id[j]] do dec(j);
31   if i<=j then
32   begin
33    swap(id[i],id[j]);
34    inc(i); dec(j);
35   end;
36  until i>j;
37  if l<j then qsort(l,j);
38  if i<r then qsort(i,r);
39 end;
40
41 function find(k:longint):longint;
42 begin
43  if fa[k]<>k then fa[k]:=find(fa[k]);
44  find:=fa[k];
45 end;
46
47 procedure merge(x,y:longint);
48 begin
49  size[y]:=size[y]+size[x];
50  mx[y]:=max(mx[x],mx[y]);
51  mn[y]:=min(mn[x],mn[y]);
52  fa[x]:=y;
53 end;
54
55 function cmp(a,b,l:longint):boolean;
56 begin
57  exit((y[a]=y[b])and(y[a+l]=y[b+l]));
58 end;
59
60 procedure getsa(n:longint);
61 var i,j,p:longint;
62 begin
63  for i:=0 to n-1 do
64  begin
65   x[i]:=a[i];
66   inc(wc[a[i]]);
67  end;
68  for i:=1 to m-1 do wc[i]:=wc[i-1]+wc[i];
69  for i:=n-1 downto 0 do
70  begin
71   dec(wc[x[i]]);
72   sa[wc[x[i]]]:=i;
73  end;
74  j:=1; p:=1;
75  while p<n do
76  begin
77   p:=0;
78   for i:=n-j to n-1 do
79   begin
80    y

:=i; inc(p); 81 end; 82 for i:=0 to n-1 do 83 if sa[i]>=j then begin y[p]:=sa[i]-j; inc(p); end; 84 for i:=0 to n-1 do wd[i]:=x[y[i]]; 85 for i:=0 to m-1 do wc[i]:=0; 86 for i:=0 to n-1 do inc(wc[wd[i]]); 87 for i:=1 to m-1 do wc[i]:=wc[i-1]+wc[i]; 88 for i:=n-1 downto 0 do 89 begin 90 dec(wc[wd[i]]); 91 sa[wc[wd[i]]]:=y[i]; 92 end; 93 for i:=0 to n do swap(x[i],y[i]); 94 p:=1; x[sa[0]]:=0; 95 for i:=1 to n-1 do 96 if cmp(sa[i-1],sa[i],j) then x[sa[i]]:=p-1 97 else 98 begin 99 x[sa[i]]:=p; inc(p); 100 end; 101 j:=j*2; 102 m:=p; 103 end; 104 end; 105 106 procedure getheight(n:longint); 107 var i,j,k:longint; 108 begin 109 for i:=1 to n do rank[sa[i]]:=i; 110 k:=0; 111 for i:=0 to n-1 do 112 begin 113 if k>0 then dec(k); 114 j:=sa[rank[i]-1]; 115 while a[i+k]=a[j+k] do inc(k); 116 height[rank[i]]:=k; 117 end; 118 end; 119 120 begin 121 assign(input,'bzoj4199.in'); reset(input); 122 assign(output,'bzoj4199.out'); rewrite(output); 123 readln(n); 124 readln(ch); 125 for i:=0 to n-1 do a[i]:=ord(ch[i+1])-ord('a')+1; 126 a :=0; m:=300; 127 getsa(n+1); 128 getheight(n); 129 for i:=0 to n-1 do read(b[i]); 130 for i:=1 to n do 131 begin 132 fa[i]:=i; 133 size[i]:=1; mx[i]:=b[sa[i]]; mn[i]:=mx[i]; 134 f[i]:=-oo; 135 end; 136 f[0]:=-oo; 137 for i:=1 to n-1 do id[i]:=i+1; 138 qsort(1,n-1); 139 for i:=1 to n-1 do 140 begin 141 p:=find(id[i]-1); q:=find(id[i]); 142 t:=height[id[i]]; 143 sum[t]:=sum[t]+int64(size[p])*size[q]; 144 f[t]:=max(f[t],int64(mx[p])*mx[q]); 145 f[t]:=max(f[t],int64(mx[p])*mn[q]); 146 f[t]:=max(f[t],int64(mn[p])*mx[q]); 147 f[t]:=max(f[t],int64(mn[p])*mn[q]); 148 merge(p,q); 149 end; 150 for i:=n-2 downto 0 do 151 begin 152 sum[i]:=sum[i]+sum[i+1]; 153 f[i]:=max(f[i],f[i+1]); 154 end; 155 for i:=0 to n-1 do 156 if f[i]>-oo then writeln(sum[i],' ',f[i]) 157 else writeln(0,' ',0); 158 159 close(input); 160 close(output); 161 end.

[p] 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: