zoukankan      html  css  js  c++  java
  • String HDU

    String

     HDU - 4821 

    题意:求长串中存在多少个长度为M*L的子串(是由M个长度为L的子串构成的)

    算是第一道哈希题了,看的别人的代码

    先求出原串左边起到第i位的哈希值h[i],然后枚举起点,计算出前M段,然后利用滑动窗口右移,因此起点只需从1枚举到L即可

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ull unsigned long long
     4 const int maxn=100010;
     5 const int seed=31;
     6 
     7 char s[maxn];
     8 int M,L;
     9 ull h[maxn],base[maxn];
    10 map<ull,int> mp;
    11 ull _hash(int l,int r)  //求区间l到r的哈希值
    12 {
    13     return  h[r]-h[l-1]*base[r-l+1];
    14 }
    15 
    16 int main()
    17 {
    18     base[0]=1;
    19     for(int i=1;i<maxn;i++)
    20         base[i]=base[i-1]*seed;
    21     while(scanf("%d%d",&M,&L)!=EOF){
    22         scanf("%s",s+1);
    23         int len=strlen(s+1);
    24         for(int i=1;i<=len;i++)
    25             h[i]=h[i-1]*seed+s[i]-'a'; 
    26         int ans=0;
    27         for(int i=1;i<=L&&i+M*L<=len;i++){   
    28             mp.clear();
    29             for(int j=i;j<i+M*L;j+=L){
    30                 ull x=_hash(j,j+L-1);
    31                 mp[x]++;
    32             }
    33             if(mp.size()==M)ans++;
    34             //下面相当于为M段的滑动窗口,每次右移判断是否满足
    35             for(int j=i+M*L;j+L-1<=len;j+=L){
    36                 ull x=_hash(j,j+L-1);
    37                 mp[x]++;  //右边进来
    38                 ull y=_hash(j-M*L,j-M*L+L-1);
    39                 mp[y]--;   //左边出去
    40                 if(mp[y]==0) mp.erase(y);
    41                 if(mp.size()==M) ans++;
    42             }
    43         }
    44         printf("%d
    ",ans);
    45     }
    46 
    47 }
    View Code
  • 相关阅读:
    CodeForces 543d Road Improvement
    UVA Foreign Exchange
    ZOJ 1825 Compound Words
    UVA 10125 Sumsets
    CodeForces
    32位linux(centos)下mongoDB的安装
    关于PHP 采集类
    关于微信支付零时工代码的修正方法
    微信公众号申请,微信支付全攻略 2
    简介CentOS与 Ubuntu的不同
  • 原文地址:https://www.cnblogs.com/yijiull/p/7388212.html
Copyright © 2011-2022 走看看