luogu 5561 [Celeste-B]Mirror Magic 后缀数组+RMQ+multiset

时间:2019-09-16
本文章向大家介绍luogu 5561 [Celeste-B]Mirror Magic 后缀数组+RMQ+multiset,主要包括luogu 5561 [Celeste-B]Mirror Magic 后缀数组+RMQ+multiset使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

思路肯定是没有问题,但是不知道为啥一直 TLE 两个点~

#include <bits/stdc++.h> 
#define N 2000006 
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std; 
multiset<int>id,len;    
multiset<int>::iterator it;      
int arr[N],st[N],length[N],idxx[N],n,m=120;
char str[N];               
namespace SA
{
    int rk[N], tp[N], tax[N], sa[N], height[N], Log[N], dp[N][22];       
    void qsort()
    {
        for(int i=0;i<=m;++i) tax[i]=0;
        for(int i=1;i<=n;++i) ++tax[rk[i]];
        for(int i=1;i<=m;++i) tax[i]+=tax[i-1];
        for(int i=n;i>=1;--i) sa[tax[rk[tp[i]]]--]=tp[i];
    }
    void construct()
    {
        for(int i=1;i<=n;++i) rk[i]=arr[i],tp[i]=i;
        qsort();
        for(int k=1;k<=n;k<<=1)
        {
            int p=0;
            for(int i=n-k+1;i<=n;++i) tp[++p]=i;
            for(int i=1;i<=n;++i) if(sa[i]>k) tp[++p]=sa[i]-k;
            qsort(), swap(tp,rk), rk[sa[1]]=p=1;
            for(int i=2;i<=n;++i)
                rk[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+k]==tp[sa[i]+k])?p:++p;
            if(p==n) break;
            m=p;
        }
        int k=0;
        for(int i=1;i<=n;++i) rk[sa[i]]=i;
        for(int i=1;i<=n;++i)
        {
            if(k)--k;
            int j=sa[rk[i]-1];
            while(arr[i+k]==arr[j+k])++k;
            height[rk[i]]=k;
        }
    }
    void RMQ()
    {   
        for(int i=2;i<=n;++i) Log[i]=Log[i>>1]+1;    
        for(int i=1;i<=n;++i) dp[i][0]=height[i];
        for(int j=1;(1<<j)<=n;++j)
            for(int i=1;i+(1<<j)-1<=n;++i)
                dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
    }
    inline int getmin(int a,int b)
    {
        int k=Log[b-a+1];    
        return min(dp[a][k],dp[b-(1<<k)+1][k]);
    }
};
int main() 
{ 
    int i,j,pp,nn,q;  
    // setIO("input"); 
    scanf("%d",&pp);      
    for(i=1;i<=pp;++i) 
    {
        scanf("%s",str+1); 
        nn=strlen(str+1); 
        st[i]=n+1; 
        for(j=1;j<=nn;++j) arr[++n]=str[j]-'a'+1;   
        arr[++n]=30;         
    } 
    SA::construct(); 
    SA::RMQ();   
    scanf("%d",&q);                   
    for(i=1;i<=q;++i) 
    {
        int opt; 
        scanf("%d",&opt); 
        if(opt==1) 
        {
            int x,l,r,tmp;   
            scanf("%d%d%d",&x,&l,&r); 

            tmp=st[x]+l-1;        
            idxx[i]=SA::rk[tmp];    
            length[i]=r-l+1;
  
            id.insert(idxx[i]);                            
            len.insert(r-l+1);                

            int a=(*id.begin()),b=(*(--id.end()));   

            if(a==b) 
            {
                printf("%d\n",*len.begin());              
            }
            else 
            {
                printf("%d\n",min(*len.begin(),SA::getmin(a+1,b)));        
            }
        }
        else 
        { 
            int k; 
            scanf("%d",&k);     

            len.erase(len.lower_bound(length[k]));      
            id.erase(id.lower_bound(idxx[k]));         

            if(len.empty()) 
            {
                printf("0\n"); 
                continue;  
            }

            int a=(*id.begin()),b=(*(--id.end()));     

            if(a==b) 
            {
                printf("%d\n",*len.begin()); 
            }
            else 
            {
                printf("%d\n",min(*len.begin(),SA::getmin(a+1,b)));          
            }
        }
    }
    return 0; 
} 

  

原文地址:https://www.cnblogs.com/guangheli/p/11525390.html