zoukankan      html  css  js  c++  java
  • CodeForces 113B Petr#

    题目链接:http://codeforces.com/problemset/problem/113/B

    题目大意:

    多组数据
    每组给定3个字符串T,Sbeg,Sed,求字符串T中有多少子串是以Sbeg开头,Sed结尾的

    分析:

      难点在哈希函数的编写,如果直接存string会爆内存,不能用STL自带哈希函数,用了会Wa。

    代码如下:

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3  
      4 #define rep(i,n) for (int i = 0; i < (n); ++i)
      5 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
      6 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
      7 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
      8 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
      9  
     10 #define pr(x) cout << #x << " = " << x << "  "
     11 #define prln(x) cout << #x << " = " << x << endl
     12  
     13 #define ALL(x) x.begin(),x.end()
     14 #define INS(x) inserter(x,x.begin())
     15  
     16 #define ms0(a) memset(a,0,sizeof(a))
     17 #define msI(a) memset(a,inf,sizeof(a))
     18  
     19 #define pii pair<int,int> 
     20 #define piii pair<pair<int,int>,int> 
     21 #define mp make_pair
     22 #define pb push_back
     23 #define fi first
     24 #define se second
     25  
     26 inline int gc(){
     27     static const int BUF = 1e7;
     28     static char buf[BUF], *bg = buf + BUF, *ed = bg;
     29      
     30     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
     31     return *bg++;
     32 } 
     33  
     34 inline int ri(){
     35     int x = 0, f = 1, c = gc();
     36     for(; c<48||c>57; f = c=='-'?-1:f, c=gc());
     37     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
     38     return x*f;
     39 }
     40  
     41 typedef long long LL;
     42 typedef unsigned long long uLL;
     43 const LL mod = 1e9 + 7;
     44 const int maxN = 2000 + 7;
     45  
     46 string T, Sbeg, Sed;
     47 unordered_set< LL > sll;
     48 int beg[maxN], begLen; // 记录 Sbeg出现的位置 
     49 int ed[maxN], edLen; // 记录 Sed出现的位置 
     50  
     51 // h为T的后缀哈希数组 
     52 // h[i]表示T从i位置开始的后缀的哈希值 
     53 // h[i] = T[i] + T[i+1]*key + T[i+2]*key^2 + ……+ T[i+len-1-i]*key^len-1-i
     54 // xp为基数数组
     55 // xp[i] = key^i
     56 LL xp[maxN], h[maxN];
     57 const LL key = 1e9 + 7;
     58  
     59 // 求起点为s,长为len的子串的哈希值 
     60 // Hash(i, len) = T[i] + T[i+1]*key + T[i+2]*key^2 + ……+ T[i+len-1]*key^len-1
     61 LL Hash(int s, int len) {
     62     return h[s] - h[s + len] * xp[len];
     63 }
     64   
     65 void HashInit(const char* s, LL* h, int len) {
     66     xp[0] = 1;
     67     For(i, 1, maxN - 1) xp[i] = xp[i - 1] * key;
     68          
     69     h[len] = 0;
     70     rFor(i, len - 1, 0) h[i] = h[i + 1] * key + s[i];        
     71 }
     72  
     73 int main(){
     74     while(cin >> T >> Sbeg >> Sed) {
     75         HashInit(T.c_str(), h, (int)T.size());
     76          
     77         int ans = 0;
     78         sll.clear();
     79         begLen = edLen = 0;
     80          
     81         int p = 0;
     82         while(p < T.size()) {
     83             int t = T.find(Sbeg.c_str(), p);
     84             if(t == string::npos) break;
     85             beg[begLen++] = t;
     86             p = t + 1;
     87         }
     88          
     89         p = 0;
     90         while(p < T.size()) {
     91             int t = T.find(Sed.c_str(), p);
     92             if(t == string::npos) break;
     93             ed[edLen++] = t;
     94             p = t + 1;
     95         }
     96          
     97         int i = 0, j = 0;
     98         while(i < begLen && j < edLen) {
     99             if(beg[i] <= ed[j]) {
    100                 For(k, j, edLen - 1) {
    101                     if(beg[i] + Sbeg.size() > ed[k] + Sed.size()) continue;
    102                     sll.insert(Hash(beg[i], ed[k] + Sed.size() - beg[i]));
    103                 }
    104                 ++i;
    105             }
    106             else ++j;
    107         }
    108          
    109         cout << sll.size() << endl;
    110     }
    111     return 0;
    112 }
    View Code
  • 相关阅读:
    centos 安装 TortoiseSVN svn 客户端
    linux 定时任务 日志记录
    centos6.5 安装PHP7.0支持nginx
    linux root 用户 定时任务添加
    composer 一些使用说明
    laravel cookie写入
    laravel composer 安装指定版本以及基本的配置
    mysql 删除重复记录语句
    linux php redis 扩展安装
    linux php 安装 memcache 扩展
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/10733044.html
Copyright © 2011-2022 走看看