zoukankan      html  css  js  c++  java
  • 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
    */
  • 相关阅读:
    通过分析SQL语句的执行计划优化SQL(总结)
    Oracle中视图的创建和处理方法
    深入Oracle视图编写的示例
    Oracle数据库设计规范化的前两个要求
    ORACLE执行计划的一些基本概念
    养成一个SQL好习惯带来一笔大财富
    数据库管理方面的电子书下载地址汇总
    matlab C程序
    yum安装mysql
    Valgrind调试
  • 原文地址:https://www.cnblogs.com/wulangzhou/p/3438886.html
Copyright © 2011-2022 走看看