codevs1356 bzoj2746 jsoi2012

来源:互联网 发布:软件 设计说明书 编辑:程序博客网 时间:2024/06/12 00:26
codevs1356 <wbr> <wbr>bzoj2746 <wbr> <wbr>jsoi2012

codevs1356 <wbr> <wbr>bzoj2746 <wbr> <wbr>jsoi2012

codevs1356 <wbr> <wbr>bzoj2746 <wbr> <wbr>jsoi2012

codevs1356 <wbr> <wbr>bzoj2746 <wbr> <wbr>jsoi2012

题目描述 Description

yz 是 Z国的领导人,他规定每个地区的名字只能为 26 个小写拉丁字母的一个。由于地
区数有可能超过 26 个,便产生了一个问题,如何辨别名字相同的地区?于是 yz 规定,一个
地区的描述必须包含它的所有上级,且上级按次序排列。于是,一个地区的描述是一个字符
串。比如说,一个地区的名字为 c,它的上级为 b,b 的上级为 a,a 没有上级,那么这个地
区就描述为 abc。显然,这个描述同时包含了 c 的上级 b 和 b 的上级 a 的描述,分别为 ab
和a。

值得注意的是,每个地区最多有一个上级,同一上级的地区之间名字不同,没有上级的
地区之间名字不同。 
现在,yz 对外公布了 n 个地区的描述,这些描述中包含了 Z 国所有地区的描述,并让
你处理来访者的旅行问题。 
现有 m 对人访问这个国家,对于每对人,第一个人喜欢第 i 个描述中的第 j 个地区,设
这个地区描述为 s1,第二个人喜欢第 k 个描述中的第 l 个地区,设这个地区描述为 s2。他
们为了统一行程,决定访问描述为 s 的地区(显然他们只关心地区的名字,并非是地区本身),
设 s 的长度为 t,s 需要满足以下条件: 
1:t<=j, t<=l; 
2:s[1..t] = s1[j-t+1 … j], s[1..t] = s2[l-t+1 … l];(即s为s1中1到k位与 s2中 1 到 l 位的公共后缀) 
3:t 最大化。 
为了不使输出过大,你只需把这个字符串按照如下生成的 26 进制数转成 10 进制后 mod 1000000007后输出: 
a->0 
b->1 



z->25 
比如地区 cab 被编码成 2 * 26^2+ 0 * 26^1+ 1 * 26^0= 1353。

输入描述 InputDescription

第一行给定一个整数n 
第 2…n+1 行:每 i+1 行给定一个字符串 a[i],表示第 i个描述。 
接下来一行一个整数 m 
接下来 m 行:每行给定四个整数 i,j,k,l,字母含义与题目描述一致。

输出描述 OutputDescription

共 m行,每行一个整数,表示答案字符串的编码。 

样例输入 SampleInput


aabb 
babb 

1 3 2 3 
1 4 2 4

样例输出 SampleOutput


1

数据范围及提示 Data Size &Hint

询问 1中的公共后缀有 ab 和 b,但是没有 ab 这个地区,只有 b 地区,所以只能选择 b 这个
地区; 
询问 2 中的公共后缀有 abb、bb 和 b,但是没有 abb 和 bb 这两个地区,只有 b 地区,所以
只能选择 b 这个地区。

设这个国家地区总数数为 tot(注意:输入的字符串总长度可能超过 tot!) 
对于 30%的数据,满足 tot,m,n<=100; 
对于 50%的数据,满足 tot,m,n<=1000; 
对于 80%的数据,满足 tot,m,n<=100000; 
对于 100%的数据,满足 tot,m,n<=1000000; 
保证输入文件不超过 20MB。



然后你们应该可以想象这道题妈的卡了我多少时间了么。。。。(可能是我自己太弱了
一开始只是想刷刷水题然后半小时打好代码(用的是指针,后来发现自己MLE然后改成数组 然后又T(因为用了map  然后又改成指针 最后又手打hash  最后丧心病狂卡空间 还好codevs上可以看自己的错误信息  此处感谢wphorzorz

其实一开始看到题目我们应该想得到这一题就是裸的ac自动机上的失配边构成的树的树上lca(有点绕 如果不理解仔细想想  这个很重要) 一开始傻逼没有存每个节点对应的编码果断T了 后来才发现每个点的编码可以预先搞出来=。=
附代码:
#include
#include
#include
using namespace std;
#define min(a,b) (a
#define youhua __attribute__((optimize("O2")))
int con=1;
int root=1;

struct node
{
int len;
short data;
int ff,ch[26],f[19 ];
int ans;
youhua inline node(int fa,shortda){ff=fa;for(len=0;len<26;len++)f[min(len,18)]=ch[len]=0;len=0;data=da;ans=0;};
    youhua inlinenode(){ff=0;for(len=0;len<26;len++)f[min(len,18)]=ch[len]=0;len=0;data=-1;ans=0;}
}ac[1001001];

char c;  
//youhua inline void read(int &a)
//{
// a=0;
// do c=getchar();while(c<'0'||c>'9');
//while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
//}

char  s1[1000001];
int line[1001001];
struct Node
{
int x,y;
youhua inline friend bool operator  ==(Nodea,Node b)
{ return (a.x==b.x&&a.y==b.y); }
youhua inline friend bool operator  !=(Nodea,Node b)
{ return (a.x!=b.x||a.y!=b.y); }
};

struct chain{
Node a;
chain *next;
int data;
youhua chain(Node sa,chain *b,int ad){a=sa,next=b,data=ad;}
};

long long place;
struct hillan
{
chain *head[1007001];
    chain *temp;
    
youhua inline void push(int i,int j,int k)
{
place=(i*13237ll+j)07000;
head[place]=new chain((Node){i,j},head[place],k);
}
youhua inline int find(int i,int j)
    {
   
place=(i*13237ll+j)07000;
      for(temp=head[place];temp->a.x!=i&&temp->a.y!=j;temp=temp->next);
       return temp->data;
}
}m;

const
 long long mod=1000000007;
//map mm;
int j,len1,i,temp;
long long res;
youhua inline void insert()
{
res=1;
temp=root;
for(j=0;j
 //mm[(Node){i,j}]=ac[temp].ch[s1[j]-'a'],temp=ac[temp].ch[s1[j]-'a'];
     res*=26,m.push(i,j,ac[temp].ch[s1[j]-'a']),temp=ac[temp].ch[s1[j]-'a'];
for(;j
     ac[++con].data=s1[j]-'a';
 ac[con].ff=temp;
 ac[con].ans=(ac[ac[con].ff].ans*26ll+s1[j]-'a')%mod;
 res*=26;
 res%=mod;
 temp=ac[temp].ch[s1[j]-'a']=con;
 m.push(i,j,con);}//mm[(Node){i,j}]=con; 
 
 if(con>1001000)
  printf("MLE"),exit(0); 
}


int l,r;
youhua inline void build()
{
l=1,r=1;
line[l]= root;
ac[root].f[0]=0;
for(i=0;i<26;i++)
if(ac[line[l]].ch[i])line[++r]=ac[line[l]].ch[i];
while(++l<=r)
   {
   temp=ac[ac[line[l]].ff].f[0];
   for(;temp&&!ac[temp].ch[ac[line[l]].data];temp=ac[temp].f[0]);
   if(!temp)
     ac[line[l]].f[0]=root;
   elseac[line[l]].f[0]=ac[temp].ch[ac[line[l]].data];
ac[line[l]].len=ac[ac[line[l]].f[0]].len+1;
 //- addside(line[l]->f[0],line[l]);
      for(i=0;i<26;i++)
       if(ac[line[l]].ch[i])line[++r]=ac[line[l]].ch[i];     
}
ac[line[1]].f[0]=line[1];
for(i=1;i<=r;i++)
     for(j=1;j<=18;j++)
      ac[line[i]].f[j]=ac[ac[line[i]].f[j-1]].f[j-1];
}
//youhua inline void read(char *a)
//{
// len1=-1;
// do c=getchar();while(c<'a'||c>'z');
//while(c<='z'&&c>='a')a[++len1]=c,c=getchar();len1++;
//}


youhua int main()
{

int n;i=1;
    //read(n);
n=0;
do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')n=(n<<3)+(n<<1)+c-'0',c=getchar();
while(i<=n)
{
// read(s1);
 // scanf("%s",s1);
  len1=-1;
   doc=getchar();while(c<'a'||c>'z');
  while(c<='z'&&c>='a')s1[++len1]=c,c=getchar();len1++;
  insert();
   i++;
}
build();
int i;
//read(n);
n=0;
do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')n=(n<<3)+(n<<1)+c-'0',c=getchar();
int j,k,l,t;
int aa,bb;
// long long ans;
//long long res;
while(n--)
{
  //read(i),read(j),read(k),read(l);
i=0;
do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')i=(i<<3)+(i<<1)+c-'0',c=getchar();
      j=0;
do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')j=(j<<3)+(j<<1)+c-'0',c=getchar();
     k=0;
do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')k=(k<<3)+(k<<1)+c-'0',c=getchar();
l=0;
do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')l=(l<<3)+(l<<1)+c-'0',c=getchar();
aa=m.find(i,j-1);
   bb=m.find(k,l-1);
if(ac[aa].len
    swap(aa,bb);
   if(bb==root)
    {
     putchar('0');putchar('\n');
     continue;
 }
while(ac[aa].len!=ac[bb].len)
{
        for(j=0;ac[ac[aa].f[j+1]].len>=ac[bb].len;j++) ;
     aa=ac[aa].f[j];
}
while(aa!=bb)
{
 for(j=0;ac[aa].f[j+1]!=ac[bb].f[j+1];j++);
 aa=ac[aa].f[j];
 bb=ac[bb].f[j];
}
// ans=0;
// res=1;
// while(aa!=root)
// {
// ans+=ac[aa].data*res;
// res*=26;
// ans%=mod;
// res%=mod;
// aa=ac[aa].ff;
// }
printf("%lld\n",ac[aa].ans);   
}
return 0;
}

0 0
原创粉丝点击