zoukankan      html  css  js  c++  java
  • 牛客 白兔的字符串

    题目

    白兔有一个字符串T。白云有若干个字符串S1,S2..Sn。

    白兔想知道,对于白云的每一个字符串,它有多少个子串是和T循环同构的。

    提示:对于一个字符串a,每次把a的第一个字符移动到最后一个,如果操作若干次后能够得到字符串b,则a和b循环同构。

    所有字符都是小写英文字母

    思路

    首先需要需要循环同构,那么我们需要一个常规的东西叫做破环成链,然后枚举长度是T的字符串,那么他询问的字串一定是这些字符串里面的一个,然后我们对于每一个询问去求出长度为len的子串的hash值,然后去lower_bound就可以了。主要是熟悉字串hash 的基本操作,包括如何求一个子段的hash值。

    代码实现

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<set>
    #include<map>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define MT(x,i) memset(x,i,sizeof(x) )
    #define rev(i,start,end) for (int i=start;i<end;i++)
    #define inf 0x3f3f3f3f
    #define mp(x,y) make_pair(x,y)
    #define lowbit(x) (x&-x)
    #define MOD 1000000007
    #define exp 1e-8
    #define N 1000005 
    #define fi first 
    #define se second
    #define pb push_back
    typedef long long ll;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    typedef unsigned long long ull;
    typedef vector <int> VI;
    typedef pair<int ,int> PII;
    typedef pair<int ,PII> PIII;
    ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
    void check_max (int &a,int b) { a=max (a,b);}
    void check_min (int &a,int b) { a=min (a,b);}
    inline int read() {
        char ch=getchar(); int x=0, f=1;
        while(ch<'0'||ch>'9') {
            if(ch=='-') f=-1;
            ch=getchar();
        } while('0'<=ch&&ch<='9') {
            x=x*10+ch-'0';
            ch=getchar();
        } return x*f;
    }
    
    const int maxn=2e6+10;
    ull fac[maxn],hashed[maxn];
    int base=131;
    char ss[maxn],s[maxn];
    
    int main () {
        scanf ("%s",ss);
        int len=strlen (ss);
        rev (i,0,len) ss[i+len]=ss[i];
        ull hash=0,cnt=0;
        fac[0]=1;
        rep (i,1,maxn) fac[i]=fac[i-1]*base;
        int num=0;
        rev (i,0,2*len-1) {
            hash=hash*base+ss[i];
            cnt++;
            if (cnt==len) {
                hashed[++num]=hash;
                cnt--;
                hash-=fac[len-1]*ss[i-len+1];
            } 
        }
        sort (hashed+1,hashed+1+num);
        int n;
        scanf ("%d",&n);
        rep (i,1,n) {
            scanf ("%s",s);
            int lens=strlen (s);
            hash=0,cnt=0;
            int ans=0;
            rev (j,0,lens) {
                hash=hash*base+s[j];
                cnt++;
                if (cnt==len) {
                    cnt--;
                    int pos=lower_bound (hashed+1,hashed+1+num,hash)-hashed-1;
                    if (pos<num&&hashed[pos+1]==hash) ans++;
                    hash-=fac[len-1]*s[j-len+1];
                }
            }
            printf ("%d
    ",ans);
        }
    
    
    
        return 0;
    }
    
  • 相关阅读:
    个人应该做什么样的网站?
    得对xls文件作操作
    正则替换
    31 反馈的判断方法(2)
    AD 层次原理图设计 自上而下
    27 多级放大电路的频率响应与第四章集成运放的电流源电路
    P28 集成运放的电流源电路(2)
    32 负反馈放大电路的方块图
    ESP8266固件AT指令连接EMQ 的MQTT服务器
    33 深度负反馈的实质与放大倍数分析
  • 原文地址:https://www.cnblogs.com/hhlya/p/13851231.html
Copyright © 2011-2022 走看看