zoukankan      html  css  js  c++  java
  • 51nod-1732 婚姻介绍所(后缀数组)

    题目大意:回答任意两个子串的最长公共前缀。

    题目分析:后缀数组的模板题。但是输入输出都要外挂。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int N=1000;
    
    int n,m;
    char s[N+5];
    int cnt[N+5],SA[N+5];
    int rk[N+5],tSA[N+5];
    int height[N+5];
    int ans[N+5][N+5];
    
    void in(int &x)
    {
    	x=0;
    	char c=getchar();
    	while(c<'0'||c>'9'){
    		c=getchar();
    	}
    	x=c-'0';
    	while(c=getchar()){
    		if(c<'0'||c>'9') break;
    		x=x*10+c-'0';
    	}
    }
    
    void out(int x)
    {
    	if(x>=10)
    		out(x/10);
    	putchar(x%10+'0');
    }
    
    bool same(int *y,int i,int j,int k)
    {
    	if(y[SA[i]]!=y[SA[j]]) return false;
    	if(SA[i]+k>=n&&SA[j]+k>=n) return true;
    	if(SA[i]+k<n&&SA[j]+k>=n) return false;
    	if(SA[i]+k>=n&&SA[j]+k<n) return false;
    	return y[SA[i]+k]==y[SA[j]+k];
    }
    
    void buildSA()
    {
    	m=130;
    	int *x=rk,*y=tSA;
    	for(int i=0;i<m;++i) cnt[i]=0;
    	for(int i=0;i<n;++i) ++cnt[x[i]=s[i]];
    	for(int i=1;i<m;++i) cnt[i]+=cnt[i-1];
    	for(int i=n-1;i>=0;--i) SA[--cnt[x[i]]]=i;
    	for(int k=1;k<=n;k<<=1){
    		int p=0;
    		for(int i=n-k;i<n;++i) y[p++]=i;
    		for(int i=0;i<n;++i) if(SA[i]>=k) y[p++]=SA[i]-k;
    		for(int i=0;i<m;++i) cnt[i]=0;
    		for(int i=0;i<n;++i) ++cnt[x[y[i]]];
    		for(int i=1;i<m;++i) cnt[i]+=cnt[i-1];
    		for(int i=n-1;i>=0;--i) SA[--cnt[x[y[i]]]]=y[i];
    		p=1;
    		swap(x,y);
    		x[SA[0]]=0;
    		for(int i=1;i<n;++i){
    			if(same(y,i,i-1,k)) x[SA[i]]=p-1;
    			else x[SA[i]]=p++;
    		}
    		if(p>=n) break;
    		m=p;
    	}
    }
    
    void getHeight()
    {
    	for(int i=0;i<n;++i)
    		rk[SA[i]]=i;
    	height[0]=0;
    	for(int i=1;i<n;++i){
    		int k=0;
    		while(s[SA[i]+k]==s[SA[i-1]+k]) ++k;
    		height[i]=k;
    	}
    }
    
    void getAns()
    {
    	for(int i=0;i<n;++i) ans[i][i]=n-i;
    	for(int i=0;i<n;++i){
    		int minn=n;
    		for(int j=i+1;j<n;++j){
    			minn=min(minn,height[j]);
    			ans[SA[i]][SA[j]]=ans[SA[j]][SA[i]]=minn;
    		}
    	}
    }
    
    int main()
    {
    	int q,a,b;
    	while(~scanf("%d",&n))
    	{
    		scanf("%s",s);
    		buildSA();
    		getHeight();
    		getAns();
    		in(q);
    		while(q--)
    		{
    			in(a);
    			in(b);
    			out(ans[a][b]);
    			puts("");
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    移动端链接、点击事件、输入框去除背景高亮
    Quartz.Net与MVC结合定时任务
    Win10上使用SVN遇到的一些问题
    Win7上的ASP.NET MVC3项目在Win10上运行的一个坑
    《SQL必知必会》学习笔记(二)
    《SQL必知必会》学习笔记(一)
    数据库知识总结(表结构操作)
    搭建三层架构(ASP.NET MVC+EF)
    python线程中的全局变量与局部变量
    ADO.NET Entity Framework学习笔录(一)
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5852822.html
Copyright © 2011-2022 走看看