zoukankan      html  css  js  c++  java
  • bzoj 4084 双旋转字符串

    给两个集合A,B,找满足要求的(a,b)的对数,可以计算对于a,哪些b成立.

    还有就是字符串hash的使用,感觉平时用字符串hash太少了.

      1 /**************************************************************
      2     Problem: 4084
      3     User: idy002
      4     Language: C++
      5     Result: Accepted
      6     Time:6456 ms
      7     Memory:290272 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <set>
     12 #include <vector>
     13 #include <algorithm>
     14 #define N 8000010
     15 #define Base 31
     16 #define Mod 1000000007
     17 using namespace std;
     18  
     19 typedef long long dnt;
     20  
     21 int n, m, ln, lm;
     22 char *sa[N], *sb[N];
     23 char buf_arr[N], *buf=buf_arr;
     24 dnt fx[N], sx[N], pow[N];
     25 int fail[N];
     26 multiset<int> stb;
     27  
     28 int hash( char *s ) {
     29     dnt rt = 0;
     30     for( int i=0; s[i]; i++ )
     31         rt = (rt*Base + s[i]-'a') % Mod;
     32     return rt;
     33 }
     34 void init_hash( int ln, char *s ) {     //  ln>=1
     35     fx[0] = s[0]-'a';
     36     for( int j=1; j<ln; j++ )
     37         fx[j] = (fx[j-1]*Base + s[j]-'a') % Mod;
     38     sx[ln-1] = s[ln-1]-'a';
     39     for( int j=ln-2; j>=0; j-- )
     40         sx[j] = ((s[j]-'a')*pow[ln-1-j] + sx[j+1]) % Mod;
     41 }
     42 void init_fail( char *s ) {
     43     fail[0] = 0;
     44     fail[1] = 0;
     45     for( int i=1; s[i]; i++ ) {
     46         int j=fail[i];
     47         while( j && s[j]!=s[i] ) j=fail[j];
     48         if( s[j]==s[i] ) 
     49             fail[i+1]=j+1;
     50         else
     51             fail[i+1]=0;
     52     }
     53 }
     54 void work1() {  //  ln > lm
     55     vector<int> vc;
     56     int ll = (ln+lm)>>1;
     57     dnt ans = 0;
     58     for( int t=1; t<=n; t++ ) {
     59         init_fail(sa[t]+ll);
     60         for( int i=0; i<ll; i++ )
     61             buf[i] = sa[t][i];
     62         for( int i=0; i<ll; i++ )
     63             buf[ll+i] = sa[t][i];
     64         init_hash(ll+ll,buf);
     65         vc.clear();
     66         int i=0, j=0;
     67         while( i<ln-1 ) {
     68             while( i<ln-1 && j<ln-ll && buf[i]==sa[t][ll+j] ) i++, j++;
     69             if( j==ln-ll ) {
     70                 dnt v;
     71                 v = fx[i+(ll+ll-ln)-1]-fx[i-1]*pow[ll+ll-ln];
     72                 v = (v%Mod+Mod) % Mod;
     73                 vc.push_back(v);
     74                 j = fail[ln-ll];
     75             }
     76             if( i==ln-1 ) break;
     77             while( j && sa[t][ll+j]!=buf[i] ) j=fail[j];
     78             if( sa[t][ll+j]!=buf[i] ) i++;
     79         }
     80         sort( vc.begin(), vc.end() );
     81         vc.erase( unique(vc.begin(),vc.end()), vc.end() );
     82         for( int t=0; t<vc.size(); t++ )
     83             ans += stb.count(vc[t]);
     84     }
     85     printf( "%lld
    ", ans );
     86 }
     87 void work3() {  //  ln = lm
     88     vector<int> vc;
     89     dnt ans = 0;
     90     for( int i=1; i<=n; i++ ) {
     91         init_hash(ln,sa[i]);
     92         vc.clear();
     93         vc.push_back( sx[0] );
     94         for( int j=1; j<ln; j++ ) {
     95             int v = ((dnt)sx[j]*pow[j]+fx[j-1]) % Mod;
     96             vc.push_back(v);
     97         }
     98         sort( vc.begin(), vc.end() );
     99         vc.erase( unique(vc.begin(), vc.end()), vc.end() );
    100         for( int t=0; t<vc.size(); t++ )
    101             ans += stb.count(vc[t]);
    102     }
    103     printf( "%lld
    ", ans );
    104 }
    105 int main() {
    106     scanf( "%d%d%d%d", &n, &m, &ln, &lm );
    107     if( ln>lm ) {
    108         for( int i=1; i<=n; i++ ) {
    109             scanf( "%s", buf );
    110             sa[i] = buf;
    111             buf += ln+1;
    112         }
    113         for( int i=1; i<=m; i++ ) {
    114             scanf( "%s", buf );
    115             sb[i] = buf;
    116             buf += lm+1;
    117         }
    118     } else {
    119         swap(n,m);
    120         swap(ln,lm);
    121         for( int i=1; i<=m; i++ ) {
    122             scanf( "%s", buf );
    123             sb[i] = buf;
    124             reverse( buf, buf+lm );
    125             buf += lm+1;
    126         }
    127         for( int i=1; i<=n; i++ ) {
    128             scanf( "%s", buf );
    129             sa[i] = buf;
    130             reverse( buf, buf+ln );
    131             buf += ln+1;
    132         }
    133     }
    134     pow[0] = 1;
    135     for( int i=1; i<=ln; i++ )
    136         pow[i] = pow[i-1]*Base % Mod;
    137     for( int i=1; i<=m; i++ ) 
    138         stb.insert( hash(sb[i]) );
    139     if( ln!=lm )
    140         work1();
    141     else
    142         work3();
    143 }
    View Code
  • 相关阅读:
    datepicker 日期连续选择(需要改源码)
    js 闭包 详解
    chorme模拟微信浏览器
    用phpmailer发邮件 中文乱码问题解决
    微信公众号-开发者-自定义菜单-CLICK事件处理
    微信公众号-开发者-自定义菜单
    腾讯创始人谈风投经验:这9种公司不能投
    微信公众号-个人开发者中心接口权限
    wamp Server2.5 配置 自定义目录
    amcharts 网页绘图插件
  • 原文地址:https://www.cnblogs.com/idy002/p/4580844.html
Copyright © 2011-2022 走看看