• SGU 505 Prefixes and suffixes


    题解   现将字符串排序; 那么某前缀在字符串中出现肯定是连续的;写几个案例就知道了;这是记录每个字符在以前缀排名的rank ; 然后将字符串反序; 再排序;依照前缀,可以知道相同名字的后缀也会出现在一段排序好的连续的字符串里面;这样得到前缀的区间为 [a,b],  [c,d]; 只要统计每个字符是否在 a 到 b 之间; 同时满足在 c 到 d 之间;            获取某个前缀的第一个匹配段字符串 和 最后一个字符串也就是 [a,b] 使用了字典树搞; 然后 再用线段树保留最大值和最小值;竟然没有超时, 啊,,哈哈;

    #include<iostream>
    #include<stdio.h>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #include<vector>
    using namespace std;
    
    struct date{
        int sta,end;
        date *next[27];
    }*root,*rot,tree[412345]; int total;
    date *creat_node(){
        for( int i = 0; i < 27; i++ )
        tree[total].next[i] = NULL;
        tree[total].sta = -1;
        tree[total].end = -1;
        return &tree[total++];
    }
    void inint( ){
        total = 0;
        root = creat_node();
        rot  = creat_node();
    }
    void insert( string &word,int i,int tab )
    {
        date *p; int len = word.length();
        if( tab )p = root;
        else     p = rot;
        for( int j = 0; j < len; j++ )
        {
            int num = word[j] - 'a';
            if( p->next[num] == NULL )
            {
                p->next[num] = creat_node();
                p->next[num]->sta = i;
            }
            p->next[num]->end = i;
            p = p->next[num];
        }
    }
    int sta,en;
    void work( string &word,int tab )
    {
        date *p; int len = word.length();
        if( tab ) p = root;
        else p = rot;
        for( int j = 0; j < len; j++ )
        {
            int num = word[j] - 'a';
            if( p->next[num] == NULL ){
                sta = -1; en = -1; return;
            }
            p = p->next[num]; sta = p->sta; en = p->end;
        }
    }
    struct DAte{
       string sss; int pos;
       bool operator <(const DAte &a )const{
           return sss < a.sss;
       }
    }arr[1123456];
    struct Date{
       int lt,rt,Max,Min,num;
    }node[1123456];
    void build( int lt,int rt,int t ){
        node[t].lt = lt; node[t].rt = rt;
        if( lt == rt ){ node[t].num = 1; node[t].Max = node[t].Min = arr[lt].pos; return; }
        int mid = ( lt+rt )>>1;
        build( lt,mid,t<<1 ); build( mid+1,rt,t<<1|1 );
        node[t].Max = max( node[t<<1].Max,node[t<<1|1].Max );
        node[t].Min = min( node[t<<1].Min,node[t<<1|1].Min );
        node[t].num = node[t<<1].num+node[t<<1|1].num;
    }
    int query( int lt,int rt,int a,int b,int t )
    {
        if( node[t].Min > b || node[t].Max < a  )return 0;
        int mid = ( node[t].lt+node[t].rt )>>1;
        if( node[t].lt == lt && node[t].rt == rt )
        {
            if( node[t].Max <= b && node[t].Min >= a )return node[t].num;
            return query( lt,mid,a,b,t<<1 ) + query( mid+1,rt,a,b,t<<1|1 );
        }
        if( node[t<<1].rt >= rt )return query( lt,rt,a,b,t<<1 );
        else if( node[t<<1|1].lt <= lt )return query( lt,rt,a,b,t<<1|1 );
        else return query(lt,mid,a,b,t<<1)+query(mid+1,rt,a,b,t<<1|1);
    }
    int main( )
    {
        int N,M; string str;
        while( scanf("%d",&N) != EOF )
        { 
            for( int i = 0; i < N; i++ )cin>>arr[i].sss;
               sort(arr,arr+N); inint();
            for( int i = 0; i < N; i++ ) arr[i].pos = i;
            for( int i = 0; i < N; i++ ) insert(arr[i].sss,i,1 );
            for( int i = 0; i < N; i++ ) reverse(arr[i].sss.begin(),arr[i].sss.end());
               sort(arr,arr+N);  build(0,N-1,1);
            for( int i = 0; i < N; i++ ) insert(arr[i].sss,i,0);
            scanf("%d",&M);
            for( int i = 1; i <= M; i++ ){
                cin>>str; work(str,1); int a = sta,c = en;
                cin>>str; reverse(str.begin(),str.end());work(str,0); int b = sta,d = en;
                if( a == -1 || b == -1 )cout<<0<<endl;
                else cout<<query( b,d,a,c,1 )<<endl;
            }
        }
        return 0;
    }
    /*
    14
    abasbssbs
    sfasffsd
    adfsas
    fdsssf
    safas
    fsadf
    fases
    sdesas
    aesdf
    sefss
    aseesaes
    fdsasesa
    seasea
    sedfsas
    11
    a a
    ab ac
    fa a
    fa s
    ac ca
    fd sa
    fd as
    se sa
    fs fd
    fd fs
    ab sb
    */
  • 相关阅读:
    PHP学习笔记:第一天自白
    记录ftpclient一下踩的坑
    log4j.xml打印mybatis sql
    ftpclient 550 permission denied
    java内部类demo
    轮播图制作
    java的引用数据类型,你知道吗???
    集合
    Java基础01
    java 自己实现字符串的匹配
  • 原文地址:https://www.cnblogs.com/wulangzhou/p/3438886.html
Copyright © 2020-2023  润新知