【POJ3294】 Life Forms(SA)

...又是TLE,对于单组数据肯定TLE不了,问题是多组的时候就呵呵了...

按height分组去搞,然后判一下是否不属于同一个串...

const maxn=100419;
var
 x,y,rank,sa,c,col,h,rec:array[0..maxn] of longint;
 pd:array[0..maxn] of boolean;
 s:ansistring;
 n,k,maxlen,cnta:longint;

function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end;
function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end;
procedure swap(var x,y:longint);var tmp:longint; begin tmp:=x;x:=y;y:=tmp; end;

procedure make;
var i,p,tot:longint;
begin
 p:=1;
 while p<n do
  begin
   fillchar(c,sizeof(c),0);
   for i:= 1 to n-p do y[i]:=rank[i+p];
   for i:= n-p+1 to n do y[i]:=0;
   for i:= 1 to n do inc(c[y[i]]);
   for i:= 1 to n do inc(c[i],c[i-1]);
   for i:= 1 to n do
    begin
     sa[c[y[i]]]:=i;
     dec(c[y[i]]);
    end;
   fillchar(c,sizeof(c),0);
   for i:= 1 to n do x[i]:=rank[i];
   for i:= 1 to n do inc(c[x[i]]);
   for i:= 1 to n do inc(c[i],c[i-1]);
   for i:= n downto 1 do
    begin
     y[sa[i]]:=c[x[sa[i]]];
     dec(c[x[sa[i]]]);
    end;
   for i:= 1 to n do sa[y[i]]:=i;
   tot:=1;
   rank[sa[1]]:=1;
   for i:= 2 to n do
    begin
     if (x[sa[i]]<>x[sa[i-1]]) or (x[sa[i]+p]<>x[sa[i-1]+p]) then inc(tot);
     rank[sa[i]]:=tot;
    end;
   p:=p<<1;
  end;
 for i:= 1 to n do sa[rank[i]]:=i;
end;

procedure makeh;
var i,p,j:longint;
begin
 p:=0; h[1]:=0;
 for i:= 1 to n do
  begin
   p:=max(p-1,0);
   if rank[i]=1 then continue;
   j:=sa[rank[i]-1];
   while (j+p<=n) and (i+p<=n) and (s[i+p]=s[j+p]) do inc(p);
   h[rank[i]]:=p;
  end;
end;

procedure init;
var i,j,tot:longint;
 s1:ansistring;
begin
 k:=n>>1;
 readln(s);
 tot:=1;
 maxlen:=length(s);
 for i:= 1 to maxlen do col[i]:=1;
 for i:= 2 to n do
  begin
   readln(s1);
   s:=s+‘#‘;
   maxlen:=max(length(s1),maxlen);
   inc(tot);
   for j:= length(s)+1 to length(s)+length(s1) do col[j]:=tot;
   s:=s+s1;
  end;
 n:=length(s);
 fillchar(c,sizeof(c),0);
 for i:= 1 to n do x[i]:=ord(s[i]);
 for i:= 1 to n do inc(c[x[i]]);
 for i:= 1 to 128 do inc(c[i],c[i-1]);
 for i:= 1 to n do
  begin
   sa[c[x[i]]]:=i;
   dec(c[x[i]]);
  end;
 tot:=1;
 rank[sa[1]]:=1;
 for i:= 2 to n do
  begin
   if x[sa[i]]<>x[sa[i-1]] then inc(tot);
   rank[sa[i]]:=tot;
  end;
 make; makeh;
end;

function check(x:longint):boolean;
var i,j,tot,cnt:longint;
begin
 fillchar(pd,sizeof(pd),false);
 pd[0]:=true; tot:=0; cnt:=0;
 if not pd[sa[1]] then inc(tot);
 pd[sa[1]]:=true;
 for i:= 2 to n do
  begin
   if h[i]<x then
    begin
     if tot>k then
      begin
       inc(cnt);
       rec[cnt]:=i-1;
      end;
     tot:=0;
     fillchar(pd,sizeof(pd),false);
     pd[0]:=true;
    end;
   if not pd[col[sa[i]]] then inc(tot);
   pd[col[sa[i]]]:=true;
  end;
 if tot>k then
  begin
   inc(cnt);
   rec[cnt]:=i-1;
  end;
 if cnt>0 then
  begin
   cnta:=cnt;
   exit(true);
  end;
 exit(false);
end;

procedure qsort(l,r:longint);
var i,j,mid,tmp:longint;
begin
 if l>r then exit;
 i:=l; j:=r;
 mid:=rec[l+random(r-l+1)];
 repeat
  while rec[i]<mid do inc(i);
  while rec[j]>mid do dec(j);
  if i<=j then
   begin
    swap(i,j);
    inc(i); dec(j);
   end;
 until i>j;
 qsort(i,r); qsort(l,j);
end;

procedure solve;
var l,r,mid,tot,ans,i,j:longint;
begin
 l:=1; r:=maxlen;  ans:=0;
 while l<=r do
  begin
   mid:=(l+r)>>1;
   if check(mid) then
    begin
     ans:=mid;
     l:=mid+1;
    end
   else r:=mid-1;
  end;
 fillchar(pd,sizeof(pd),false);
 if ans=0 then
  begin
   writeln(‘?‘);
   exit;
  end;
 qsort(1,cnta);
 for i:= 1 to cnta do writeln(copy(s,sa[rec[i]],ans));
end;

Begin
 readln(n);
 while n<>0 do
  begin
   init;
   solve;
   writeln;
   readln(n);
  end;
End.
时间: 2024-07-29 14:24:36

【POJ3294】 Life Forms(SA)的相关文章

【POJ3294】Life Forms(后缀数组,二分)

题意: n<=100 len[i]<=1000 思路:这是一道论文题 1 var a,x,y,sa,rank,height,wc,wd,ans,flag,b:array[0..200000]of longint; 2 ch:array[1..200]of ansistring; 3 n,n1,l,r,mid,last,i,j,m,len:longint; 4 5 procedure swap(var x,y:longint); 6 var t:longint; 7 begin 8 t:=x;

【转】Xamarin Forms 介绍

特此声明,本篇博文转自:http://blog.csdn.net/kinfey/article/details/29621381 什么是 Xamarin Forms ? Xamarin Forms 是一个高效创建跨平台用户界面的库 .通过Xamarin Forms 可以一次编码生成基于主流移动平台(iOS, Android, Windows Phone)的应用界面.和HTML 5 不同, 它是一套原生的界面解决方案,这意味着通过Xamarin Forms 渲染的界面是与底层API 紧密相连, 那

【POJ3415】 Common Substrings (SA+单调栈)

这道是求长度不小于 k 的公共子串的个数...很不幸,我又TLE了... 解法参考论文以及下面的链接 http://www.cnblogs.com/vongang/archive/2012/11/20/2778481.html http://hi.baidu.com/fpkelejggfbfimd/item/5c76cfcba28fba26e90f2ea6 1 const maxn=200419; 2 var 3 c,h,rank,sa,x,y,stack:array[0..maxn] of l

【Winform】 无法将类型为“System.Windows.Forms.SplitContainer”的对象强制转换为类型“System.ComponentModel.ISupportInitialize”。

问题:将dotnet framework 4.0 切换到2.0时,编译没有问题,在运行时出现如下错误:System.InvalidCastException: 无法将类型为“System.Windows.Forms.SplitContainer”的对象强制转换为类型“System.ComponentModel.ISupportInitialize”. 解决方法: 注释掉如下代码(此代码为设计器自动生成代码) //((System.ComponentModel.ISupportInitialize

【转】权限管理学习 一、ASP.NET FORMS身份认证

[转]权限管理学习 一.ASP.NET Forms身份认证 说明:本文示例使用的VS2017和MVC5.系统无论大小.牛逼或屌丝,一般都离不开注册.登录.那么接下来我们就来分析下用户身份认证. 简单实现登录.注销 以前在学习.net的时候不知道什么Forms身份认证,直接用session实现登录,效果也蛮好嘛.而且用户信息存在服务端,安全.前端代码: @if (string.IsNullOrWhiteSpace(ViewBag.UserName)) { <form action="/hom

asp.net中web.config配置节点大全详解【转】

web.config 文件查找规则: (1)如果在当前页面所在目录下存在web.config文件,查看是否存在所要查找的结点名称,如果存在返回结果并停止查找. (2)如果当前页面所在目录下不存在web.config文件或者web.config文件中不存在该结点名,则查找它的上级目录,直到网站的根目录. (3)如果网站根目录下不存在web.config文件或者web.config文件中不存在该节点名则在%windir%"Microsoft.NET"Framework"v2.0.

【转】c#文件操作大全(二)

61.文件夹移动到整合操作 FolderDialog aa = new FolderDialog();            aa.DisplayDialog();            if (aa.Path != "")            {                string filename = Path.GetFileName(%%1);                string path=(aa.Path.LastIndexOf("\")

Web.config配置详解【转 】

一.认识Web.config文件 Web.config   文件是一个XML文本文件,它用来储存   ASP.NET   Web   应用程序的配置信息(如最常用的设置ASP.NET   Web   应用程序的身份验证方式),它可以出现在应用程序的每一个目录中.当你通过.NET新建一个Web应用程序后,默认情况下会在根目录自动创建一个默认的   Web.config文件,包括默认的配置设置,所有的子目录都继承它的配置设置.如果你想修改子目录的配置设置,你可以在该子目录下新建一个   Web.co

【CentOS】Linux sudo权限集中管理案例

目的 使得公司的Linux系统权限管理更规范,让每个用户拥有自己所该有的权限,防止因为某些用户的权限过大后的一些误操作,导致服务器的不正常运行. 操作 1.编辑Linux系统中的sudoers文件 [[email protected] ~]# vim /etc/sudoers #Edit by root User_Alias NETMAN = net01, net02 #用户别名 User_Alias ADMIN = admin01, admin02 User_Alias SA = %sa #定