zoukankan      html  css  js  c++  java
  • bzoj 1014 LCP 二分 Hash 匹配

    求同一字符串的两个后缀的最长公共前缀。

    将字符串按位置放到Splay中维护(每个节点还维护一下该子树的hash),然后二分前缀的长度,用splay计算出指定范围的hash,按hash是否相等来判断是否相同。


     

      1 /**************************************************************
      2     Problem: 1014
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:7188 ms
      7     Memory:4900 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <iostream>
     12 #include <cstring>
     13 #define maxn 100030
     14 using namespace std;
     15  
     16 typedef unsigned long long ulng;
     17  
     18 struct Splay {
     19     int pre[maxn], son[maxn][2], ch[maxn], siz[maxn], ntot, root;
     20     ulng hash[maxn];
     21     ulng power[maxn];
     22  
     23     int newnode( int p, int c ) {
     24         int nd = ++ntot;
     25         pre[nd] = p;
     26         son[nd][0] = son[nd][1] = 0;
     27         ch[nd] = c;
     28         siz[nd] = 1;
     29         hash[nd] = c;
     30         return nd;
     31     }
     32     void update( int nd ) {
     33         int ls = son[nd][0], rs = son[nd][1];
     34         siz[nd] = siz[ls]+siz[rs]+1;
     35         hash[nd] = hash[ls]*power[siz[rs]+1]+ch[nd]*power[siz[rs]]+hash[rs];
     36     }
     37     int build( int p, const char *str, int lf, int rg ) {   //  [lf,rg]
     38         if( lf>rg ) return 0;
     39         if( lf==rg ) return newnode(p,str[lf]-'a');
     40         int mid = (lf+rg)>>1;
     41         int nd = newnode( p, str[mid]-'a' );
     42         son[nd][0] = build( nd, str, lf, mid-1 );
     43         son[nd][1] = build( nd, str, mid+1, rg );
     44         update( nd );
     45         return nd;
     46     }
     47     void init( const char *str ) {
     48         root = ntot = 0;
     49         power[0] = 1ULL;
     50         for( int i=1; i<maxn; i++ )
     51             power[i] = power[i-1]*27ULL;
     52  
     53         root = newnode( 0, 'a'-'a' );
     54         int rnd = son[root][1] = newnode( root, 'a'-'a' );
     55         son[rnd][0] = build( rnd, str, 0, strlen(str)-1 );
     56         update( rnd );
     57         update( root );
     58     }
     59     void rotate( int nd, int d ) {
     60         int p = pre[nd];
     61         int s = son[nd][!d];
     62         int ss = son[s][d];
     63          
     64         son[nd][!d] = ss;
     65         son[s][d] = nd;
     66         if( p ) son[p][ nd==son[p][1] ] = s;
     67         else root = s;
     68  
     69         pre[s] = p;
     70         pre[nd] = s;
     71         if( ss ) pre[ss] = nd;
     72  
     73         update( nd );
     74         update( s );
     75     }
     76     void splay( int nd, int top=0 ) {
     77         while( pre[nd]!=top ) {
     78             int p = pre[nd];
     79             int nl = nd==son[p][0];
     80             if( pre[p]==top ) {
     81                 rotate( p, nl );
     82             } else {
     83                 int pp = pre[p];
     84                 int pl = p==son[pp][0];
     85                 if( nl==pl ) {
     86                     rotate( pp, pl );
     87                     rotate( p, nl );
     88                 } else {
     89                     rotate( p, nl );
     90                     rotate( pp, pl );
     91                 }
     92             }
     93         }
     94     }
     95     int find( int pos ) {
     96         int nd = root;
     97         while(1) {
     98             int ls = siz[son[nd][0]];
     99             if( nd==0 ) while(1);
    100  
    101             if( pos<=ls ) {
    102                 nd = son[nd][0];
    103             } else if( pos>=ls+2 ) {
    104                 nd = son[nd][1];
    105                 pos -= ls+1;
    106             } else return nd;
    107         }
    108     }
    109     void add_ch( int pos, int c ) {
    110         int lnd = find(pos);
    111         int rnd = find(pos+1);
    112         splay(lnd);
    113         splay(rnd,lnd);
    114         son[rnd][0] = newnode( rnd, c );
    115         splay( son[rnd][0] );
    116     }
    117     void chg_ch( int pos, int c ) {
    118         int nd = find(pos);
    119         ch[nd] = c;
    120         update( nd );
    121         splay( nd );
    122     }
    123     ulng qu_hash( int lf, int rg ) {
    124         int lnd = find(lf-1);
    125         int rnd = find(rg+1);
    126         splay( lnd );
    127         splay( rnd, lnd );
    128         return hash[son[rnd][0]];
    129     }
    130     inline int size() { return siz[root]-2; }
    131 };
    132  
    133 Splay T;
    134 char str[maxn];
    135 int m;
    136  
    137 int main() {
    138     scanf( "%s", str );
    139     T.init(str);
    140     scanf( "%d", &m );
    141     while(m--) {
    142         char ch[10];
    143         int pos, sa, sb;
    144         scanf( "%s", ch );
    145         if( ch[0]=='I' ) {
    146             scanf( "%d%s", &pos, ch );
    147             pos++;
    148             T.add_ch( pos, ch[0]-'a' );
    149         } else if( ch[0]=='R' ) {
    150             scanf( "%d%s", &pos, ch );
    151             pos++;
    152             T.chg_ch( pos, ch[0]-'a' );
    153         } else {
    154             scanf( "%d%d", &sa, &sb );
    155             sa++, sb++;
    156             if( T.qu_hash(sa,sa) != T.qu_hash(sb,sb) ) {
    157                 printf( "0
    " );
    158                 continue;
    159             }
    160             int len = T.size() - max(sa-1,sb-1) + 1;
    161             int rl = 1, rr = len;
    162             while( rl<rr ) {
    163                 int md = (rl+rr+1)>>1;
    164                 ulng ha = T.qu_hash( sa, sa+md-1 );
    165                 ulng hb = T.qu_hash( sb, sb+md-1 );
    166                 if( ha==hb ) rl = md;
    167                 else rr = md-1;
    168             }
    169             printf( "%d
    ", rl );
    170         }
    171     }
    172 }
    173  
    174 
    View Code
  • 相关阅读:
    简述Mesos API–files
    docker-compose常用命令
    Linux命令行--使用linux环境变量(转)
    docker:从 tomcat 容器连接到 mysql 容器
    开发环境、生产环境、测试环境的基本理解和区别(转)
    Linux命令行–更多bash shell命令(转)
    docker启动Mysql(转)
    Linux命令行–基本的bash shell命令
    浅谈 man 命令的日常使用
    Linux命令行–走进shell
  • 原文地址:https://www.cnblogs.com/idy002/p/4296343.html
Copyright © 2011-2022 走看看