G2. 唐纳德与子串 (Hard)
Time limit per test: 2.5 seconds

Memory limit: 512 megabytes

子串的定义是在一个字符串中连续出现的一段字符。这里,我们使用 s[l…r] 来表示 s 字符串从 l 到 r(闭区间)的子串。在本题中,字符串下标从 0 开始。显然,对于长度为 n 的字符串共有 n(n+1)2 个子串。

对于一个给定的字符串 s,唐纳德给出 q 次询问,第 i 次询问包括三个参数 li,ri,zi,问在 s[li…ri] 的所有子串***有多少个恰好为 zi。

Input
输入具有如下形式:

sql1 r1 z1l2 r2 z2⋮lq rq zq

第一行一个字符串 s。

第二行一个整数 q。

接下来每行:首先两个整数 li,ri (0≤li≤ri<|s|),然后是一个非空字符串 zi。整数和整数,整数和字符串间以单空格隔开。

字符串中只会出现 26 个小写英文字母。

数据规模约定:

对于 Easy 档:1≤|s|≤100,q≤∑|zi|≤100。
对于 Hard 档:1≤|s|≤105,q≤∑|zi|≤105。
Output
对于每次询问,输出一个整数,表示答案。
/***********************************************/
考虑离线处理。将所有查询和母串相连建后缀数组。对于每一个查询,在排好序的后缀数组中恰好有一段相对应,可以二分求得 L,R。问题就转换为在 L,R 区间内有多少后缀的下标在查询区间范围内的。这是一个非常经典的区间问题。继续考虑离线处理,从大往小将数插入,然后使用树状数组轻松解决。时间复杂度 O(nlogn)。

事实上本题的做法非常套路,所以过得人也比 F 多(???)。

据验题人说暴力加疯狂特判也能过,而且玄学优化不可卡。暴力姿势太大,比不来。
/***********************************************/

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N= 1000100;
const int M = 25000100;
vector<int>T[N];
vector<int>stop[N];
int rt[N],L[M],R[M];
int sum[M],id;
int n,m,q;
int ql,qr,ed;
char a[N>>1];
ll ans = 0;
struct SAM
{
    int son[N][26],step[N],f[N],tot,last;
    SAM(){tot=last=1;}
    void insert(int ch)
    {
        int np=++tot,p,q;
        step[np]=step[last]+1;
        for (p=last;p&&!son[p][ch];p=f[p]) {
            son[p][ch]=np;
        }
        last=np;
        if (!p){
            f[np]=1;return;
        }
        if (step[q=son[p][ch]]==step[p]+1)
        {
            f[np]=q;return;
        }
        int nq=++tot;
        step[nq]=step[p]+1;
        memcpy(son[nq],son[q],sizeof(son[q]));
        f[nq]=f[q];
        f[np]=f[q]=nq;
        for (;p&&son[p][ch]==q;p=f[p])
        {
            son[p][ch]=nq;
        }
  }
  void init(){
    int t=1;
    for (int i=0;i<n;i++){
              stop[t=son[t][a[i]-'a']].push_back(i+1);
        }
    for (int i=2;i<=tot;i++){
             T[f[i]].push_back(i);
        }
  }
}sam;
void update(int &x,int l,int r,int pos)
{
    int y=x;
    x=++id;
    sum[x]=sum[y]+1;
    L[x]=L[y];R[x]=R[y];
    if (l==r) return;
    int mid=(l+r)>>1;
    if (pos<=mid) update(L[x],l,mid,pos);
    else update(R[x],mid+1,r,pos);
}
int combine(int x,int y,int l,int r)
{
  if (x==0||y==0) return x+y;
  int res=++id;
    int mid=(l+r)>>1;
  sum[res]=sum[x]+sum[y];
  L[res]=combine(L[x],L[y],l,mid);
  R[res]=combine(R[x],R[y],mid+1,r);
  return res;
}
void dfs(int x)
{
    for (int i=0;i<stop[x].size();i++){
        update(rt[x],1,n,stop[x][i]);
    }
    for (int i=0;i<T[x].size();i++){
      int y=T[x][i];
        dfs(y);
      rt[x]=combine(rt[x],rt[y],1,n);
    }
}
int query(int x,int l,int r)
{
    if (ql<=l && r<=qr || x==0) return sum[x];
    int mid=(l+r)>>1;
    int ans=0;
    if (ql<=mid) ans+=query(L[x],l,mid);
    if (qr>mid)  ans+=query(R[x],mid+1,r);
    return ans;
}
int main(int argc, char const *argv[]) {
    scanf("%s",a);
    n=strlen(a);
    for (int i=0;i<n;i++){
         sam.insert(a[i]-'a');
    }
    sam.init();
    dfs(1);
    scanf("%d",&q);
    while (q--)
    {
      scanf("%d%d",&ql,&qr);
        ++ql;++qr;
      scanf("%s",a);
        m=strlen(a);

      ql=ql+m-1;
      int t=1;
      for(int i=0;i < m && t;i++){
            t=sam.son[t][a[i]-'a'];
        }
      printf("%d\n",query(rt[t],1,n));
    }
    return 0;
}
#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
string st;
const int N = 2000000;
struct opt
{
    int i, v;
    string t;
};
vector <opt> V[N];
int q;
int ans[N];

#define lc t[x].ch[0]
#define rc t[x].ch[1]
#define pa t[x].fa
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}

struct Node{
    int ch[2],fa,w,add;
}t[N];
inline int isR(int x){return t[pa].ch[0]!=x&&t[pa].ch[1]!=x;}
inline int wh(int x){return t[pa].ch[1]==x;}
inline void paint(int x,int d){t[x].add+=d;t[x].w+=d;}
inline void pushDown(int x){
    if(t[x].add){
        paint(lc,t[x].add);
        paint(rc,t[x].add);
        t[x].add=0;
    }
}
inline void rotate(int x){
    int f=t[x].fa,g=t[f].fa,c=wh(x);
    if(!isR(f)) t[g].ch[wh(f)]=x;t[x].fa=g;
    t[f].ch[c]=t[x].ch[c^1];t[t[f].ch[c]].fa=f;
    t[x].ch[c^1]=f;t[f].fa=x;
}
inline void pd(int x){
    if(!isR(x)) pd(t[x].fa);
    pushDown(x);
}
inline void splay(int x){
    pd(x);
    for(;!isR(x);rotate(x))
        if(!isR(pa)) rotate(wh(x)==wh(pa)?pa:x);
}
inline void Access(int x){
    for(int y=0;x;y=x,x=pa)
        splay(x),rc=y;
}
inline void Link(int x,int y){
    t[x].fa=y;
    Access(y);splay(y);paint(y,t[x].w);
}
inline void Cut(int x){
    Access(x);splay(x);paint(lc,-t[x].w);
    t[lc].fa=0;lc=0;
    //update(y);
}
inline void SetW(int x,int v){t[x].w=v;}
inline int GetW(int x){return t[x].w;}


int n,Q;
char s[N],op[20];
struct SAM{
    struct State{
        int ch[26],val,par;
    }t[N];
    int sz,root,last;
    inline int nw(int _){t[++sz].val=_;return sz;}
    inline void iniSAM(){sz=0;root=last=nw(0);}
    void extend(int c){
        int p=last,np=nw(t[p].val+1); SetW(np,1);
        while(p&&!t[p].ch[c]) t[p].ch[c]=np,p=t[p].par;
        if(!p) t[np].par=root, Link(np,root);
        else{
            int q=t[p].ch[c];
            if(t[q].val==t[p].val+1) t[np].par=q, Link(np,q);
            else{
                int nq=nw(t[p].val+1);
                memcpy(t[nq].ch,t[q].ch,sizeof(t[q].ch));
                t[nq].par=t[q].par;
                Link(nq,t[q].par);
                t[q].par=t[np].par=nq;
                Cut(q);Link(q,nq);Link(np,nq);
                while(p&&t[p].ch[c]==q) t[p].ch[c]=nq,p=t[p].par;
            }
        }
        last=np;
    }
    int Query(){
        int u=root;
        for(int i=0;i<n;i++){
            int c=s[i]-'a';
            if(t[u].ch[c]) u=t[u].ch[c];
            else return 0;
        }
        pd(u);//!!
        splay(u);
        return GetW(u);
    }
    void Insert(char c){
        extend(c-'a');
    }
}sam;


int main()
{
    // freopen("G2.in", "r", stdin);
    ios :: sync_with_stdio(0);
    cin >> st;
    cin >> q;
    sam.iniSAM();
    for (int i = 1; i <= q; ++ i)
    {
        int l, r; string t;
        cin >> l >> r >> t;
        V[r].push_back((opt){i, 1, t});
        if (l + (int)t.length() - 2 >= 0)
        V[l + (int)t.length() - 2].push_back((opt){i, -1, t});
    }
    for (int i = 0; i < st.length(); ++ i)
    {
        sam.Insert(st[i]);
        for (int j = 0; j < V[i].size(); ++ j)
        {
            n = V[i][j].t.size();
            for (int k = 0; k < n; ++ k)
                s[k] = V[i][j].t[k];
            int _=sam.Query();
            ans[V[i][j].i] += _ * V[i][j].v;
        }
    }
    for (int i = 1; i <= q; ++ i)
        cout << ans[i] << endl;
}
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int r[maxn<<1];

namespace LCT {
    int tr[maxn<<1][2],fa[maxn<<1],tag[maxn<<1];

    void pushdown(int x) {
        if (tr[fa[x]][0]==x || tr[fa[x]][1]==x) pushdown(fa[x]);
        if (tag[x]) {
            r[tr[x][0]]+=tag[x];tag[tr[x][0]]+=tag[x];
            r[tr[x][1]]+=tag[x];tag[tr[x][1]]+=tag[x];
            tag[x]=0;
        }
    }
    void rotate(int x) {
        int y=fa[x],z=fa[y],l,r;
        l=tr[y][1]==x;r=l^1;
        if (tr[z][0]==y || tr[z][1]==y) tr[z][tr[z][1]==y]=x;
        fa[x]=z;fa[y]=x;fa[tr[x][r]]=y;
        tr[y][l]=tr[x][r];tr[x][r]=y;
    }
    void splay(int x) {
        pushdown(x);
        while (tr[fa[x]][0]==x || tr[fa[x]][1]==x) {
            int y=fa[x],z=fa[y];
            if (tr[z][0]==y || tr[z][1]==y) {
                if (tr[z][0]==y ^ tr[y][0]==x) rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
    }
    void access(int x) {
        for (int y=0;x;y=x,x=fa[x])
            splay(x),tr[x][1]=y;
    }
    void add(int x,int val) {
        r[x]+=val;tag[x]+=val;
    }
    void link(int x,int y) {
        access(y);splay(y);add(y,r[x]);
        fa[x]=y;
    }
    void cut(int x) {
        access(x);splay(x);add(tr[x][0],-r[x]);
        tr[x][0]=fa[tr[x][0]]=0;
    }
    int query(int x) {
        splay(x);return r[x];
    }
}
using namespace LCT;
struct SAM {
    const static int SZ = 26;
    char a = 'a';
    struct state {
        int max, fa, go[SZ];
    };
    vector<state> st;
    int last = 1, num = 2;  // 0 is NULL, 1 is empty string

    SAM(int n) { st.resize(2 * n + 10); }
    SAM(const string& s, int n) : SAM(n) { for (auto i : s) push_back(i); }
    void push_back(char ch) {
        int c = ch - a;
        int now = last;
        last = num++;
        r[last] = 1;
        st[last] = {st[now].max + 1, 1};
        while (now && !st[now].go[c]) st[now].go[c] = last, now = st[now].fa;
        if (now) {
            int nex = st[now].go[c];
            if (st[now].max + 1 == st[nex].max) st[last].fa = nex, link(last, nex);
            else {
                st[num] = st[nex];
                st[num].max = st[now].max + 1;
                link(num, st[num].fa);
                st[last].fa = st[nex].fa = num;
                cut(nex), link(last, num), link(nex, num);
                while (now && st[now].go[c] == nex) st[now].go[c] = num, now = st[now].fa;
                num++;
            }
        } else link(last, 1);
    }
    vector<int> topsort() {
        int len = st[last].max + 1;
        vector<int> cnt(len), res(num);
        for (int i = 1; i < num; i++) cnt[st[i].max]++;
        for (int i = 1; i < len; i++) cnt[i] += cnt[i - 1];
        for (int i = 1; i < num; i++) res[cnt[st[i].max]--] = i;
        return res;
    }
    int sum(size_t x) { return query(x); }
};


struct Que {
    int idx, num, typ;
    string s;
    bool operator< (const Que& e) const {
        return idx < e.idx;
    };
};
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    string s;
    cin >> s;
    SAM sam(s.length());
    int q;
    cin >> q;
    vector<Que> xw(2 * q);
    for (int i = 0; i < q; i++) {
        int l, r;
        string t;
        cin >> l >> r >> t;
        xw[2 * i] = {l + t.length() - 1, i, 0, t};
        xw[2 * i + 1] = {r + 1, i, 1, t};
    }
    sort(xw.begin(), xw.end());
    int now = 0;
    vector<int> ans(q);
    for (auto& i : xw) {
        while (now < s.length() && now < i.idx) {
            sam.push_back(s[now]);
            now++;
        }
        int tmp = 1;
        for (auto j : i.s) {
            tmp = sam.st[tmp].go[j - 'a'];
            if (!tmp) break;
        }
        if (tmp) {
            if (i.typ) ans[i.num] += sam.sum(tmp);
            else ans[i.num] -= sam.sum(tmp);
        }
    }
    for (auto i : ans) cout << i << '\n';
}

后缀数组官方题解版

#include <bits/stdc++.h>
using namespace std;

const int N = 6e5 + 10;
const int Nlog = 20;

struct SuffixArray {
    const int L;
    vector<vector<int> > P;
    vector<pair<pair<int, int>, int> > M;
    int s[N], sa[N], rank[N], height[N];
    // s: raw string
    // sa[i]=k: s[k...L-1] ranks i (0 based)
    // rank[i]=k: the rank of s[i...L-1] is k (0 based)
    // height[i] = lcp(sa[i-1], sa[i])

    SuffixArray(const string &raw_s) : L(raw_s.length()), P(1, vector<int>(L, 0)), M(L) {
        for (int i = 0; i < L; i++)
            P[0][i] = this->s[i] = int(raw_s[i]);
        for (int skip = 1, level = 1; skip < L; skip *= 2, level++) {
            P.push_back(vector<int>(L, 0));
            for (int i = 0; i < L; i++)
                M[i] = make_pair(make_pair(P[level - 1][i], i + skip < L ? P[level - 1][i + skip] : -1000), i);
            sort(M.begin(), M.end());
            for (int i = 0; i < L; i++)
                P[level][M[i].second] = (i > 0 && M[i].first == M[i - 1].first) ? P[level][M[i - 1].second] : i;
        }
        for (unsigned i = 0; i < P.back().size(); ++i) {
            rank[i] = P.back()[i];
            sa[rank[i]] = i;
        }
    }

    // This is a traditional way to calculate LCP
    void getHeight() {
        memset(height, 0, sizeof height);
        int k = 0;
        for (int i = 0; i < L; ++i) {
            if (rank[i] == 0) continue;
            if (k) k--;
            int j = sa[rank[i] - 1];
            while (i + k < L && j + k < L && s[i + k] == s[j + k]) ++k;
            height[rank[i]] = k;
        }
        rmq_init(height, L);
    }

    int f[N][Nlog];
    inline int highbit(int x) {
        return 31 - __builtin_clz(x);
    }

    int rmq_query(int x, int y) {
        int p = highbit(y - x + 1);
        return min(f[x][p], f[y - (1 << p) + 1][p]);
    }

    // arr has to be 0 based
    void rmq_init(int *arr, int length) {
        for (int x = 0; x <= highbit(length); ++x)
            for (int i = 0; i <= length - (1 << x); ++i) {
                if (!x) f[i][x] = arr[i];
                else f[i][x] = min(f[i][x - 1], f[i + (1 << (x - 1))][x - 1]);
            }
    }

    int LongestCommonPrefix(int i, int j) {
        // getHeight() must be called first
        if (i == j) return L - i;
        if (i > j) swap(i, j);
        return rmq_query(i + 1, j);
    }

    int leftBound(int x, int len) {
        x = rank[x];
        int l = 0, r = x;
        while (l < r) {
            int mid = (l + r) / 2;
            if (LongestCommonPrefix(mid, x) < len)
                l = mid + 1;
            else r = mid;
        }
        return l;
    }

    int rightBound(int x, int len) {
        x = rank[x];
        int l = x, r = L - 1;
        while (l < r) {
            int mid = (l + r + 1) / 2;
            if (LongestCommonPrefix(mid, x) < len)
                r = mid - 1;
            else l = mid;
        }
        return l;
    }
} *S;

struct BIT {
    int c[N];
    void init() {
        memset(c, 0, sizeof c);
    }

    void add(int x, int d) {
        x++;
        while (x < N) {
            c[x] += d;
            x += x & -x;
        }
    }

    int sum(int x) {
        x++;
        int ret = 0;
        while (x) {
            ret += c[x];
            x -= x & -x;
        }
        return ret;
    }

    int sum(int l, int r) {
        if (r < l) return 0;
        return sum(r) - sum(l - 1);
    }
} bit;

struct Query {
    int qn, ql, l, r, sa_l, sa_r, id;
    vector<int> ans;
};

struct Event {
    int l, r, time, pos, type, id;
    // type=1 insert
    // type=2 query
    bool operator < (const Event &e) const {
        return time < e.time || (time == e.time && type < e.type);
    }
};

string mother;
int q;
Query d[N];
vector<Event> events;

int main() {
    cin >> mother >> q;
    for (int i = 0; i < q; ++i) {
        string str;
        d[i].id = i;
        cin >> d[i].l >> d[i].r >> str;
        d[i].qn = mother.length();
        d[i].ql = str.length();
        mother += str;
    }
    S = new SuffixArray(mother);
    S->getHeight();

    // for (int i = 0; i < S->L; ++i)
    // cout << i << " " << mother.substr(S->sa[i]) << endl;

    for (int i = 0; i < q; ++i) {
        d[i].sa_l = S->leftBound(d[i].qn, d[i].ql);
        d[i].sa_r = S->rightBound(d[i].qn, d[i].ql);
        // printf("%d %d\n", d[i].sa_l, d[i].sa_r);
    }
    for (int i = 0; i < q; ++i) {
        events.push_back((Event){d[i].sa_l, d[i].sa_r, d[i].l - 1, 0, 2, i});
        events.push_back((Event){d[i].sa_l, d[i].sa_r, d[i].r - d[i].ql + 1, 0, 2, i});
    }
    for (int i = 0; i < S->L; ++i)
        events.push_back((Event){0, 0, S->sa[i], i, 1, i});
    sort(events.begin(), events.end());
    for (Event e: events) {
        if (e.type == 1) {
            bit.add(e.pos, 1);
        } else {
            d[e.id].ans.push_back(bit.sum(e.l, e.r));
        }
    }
    for (int i = 0; i < q; ++i) {
        assert (d[i].ans.size() == 2);
        int a = d[i].ans[1] - d[i].ans[0];
        assert (a >= 0);
        printf("%d\n", a);
    }
}

Easy版code:

#include<stdio.h> 
#include<string.h> 
#include<string> 

char s[1005],h[1005];  
int next[1005];  
int q,l,r,n;  

void get_next()///求得模式串的next数组 
{  
    next[0] = -1;  
    int k = -1;  
    for (int i = 1; i < n; i++)  
    {  
        while (k > -1 && h[k + 1] != h[i])  
        {  
            k = next[k];  
        }  
        if (h[k + 1] == h[i])  
        {  
            k = k + 1;  
        }  
        next[i] = k;  
    }  
}  

int KMP()///进行匹配 
{  
    get_next();  
    int k = -1;  
    int sum=0;  
    for (int i = l; i <= r; i++ )  
    {  
        while (k >-1&& h[k + 1] != s[i])  
        {  
            k = next[k];  
        }  
        if (h[k + 1] == s[i])  
            k = k + 1;  
        if (k == n-1)  
        {  
            sum++;  
        }  
    }  
    return sum;  
}  

int main()  
{  
    int ans;  
    scanf("%s",s);  
    scanf("%d",&q);  
    while(q--)  
    {  
        scanf("%d %d %s",&l,&r,h);  
        n=strlen(h);  
        ans=KMP();  
        printf("%d\n",ans);  
    }  
    return 0;  
}  
#include<stdio.h>
#include<string.h>

int main(void)
{
    char s[100000],z[100000];
    int q;
    scanf("%s",s);
    scanf("%d",&q);
    int i,j,k,savei;
    int l,r,count;
    int lson;
    for(k=0;k<q;k++)
    {
        count=0;
        scanf("%d %d %s",&l,&r,z);
        lson=strlen(z);
        for(i=l;i<=r;i++)
    {
        j=0;
        savei=i;
        while(s[savei]==z[j]&&savei<=r&&lson<=(r-l+1)&&j<lson)
        {
            savei++;
            j++;
        }
        if(j==lson)
            count++;
    }
    printf("%d\n",count);
    }
}
#include <iostream>
#include <string>
using namespace std;
int main()
{
    int q,l,r;
    string s,z;
    cin>>s;
    cin>>q;
    while(q--){
        cin>>l>>r;
        cin>>z;
        string a=s.substr(l,r-l+1);
        int p=0,i=0;
        while(( p=a.find(z,p))!=-1){
            p++;
            i++;        
        }
        cout<<i<<endl;
    }
    return 0;
} 
#include<iostream>
using namespace std;
int main()
{
    string s;
    cin>>s;
    int q;
    cin>>q;
    while(q--)
    {
        int a,b,count=0;
        cin>>a>>b;
        string str1;
        cin>>str1;
        int leng = str1.length();
        for(int i=a;i+leng-1<=b;i++)
        {
            if(s.substr(i,leng)==str1)count++;
        }
        cout<<count<<endl;  
    }
}
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
#define FOR(i, a, b) for(LL i = (a); i < (b); ++i)
const LL maxn = 110;
char s[maxn], s2[maxn];
LL q, l1, l2;
int main() {
    scanf("%s%lld", s, &q); l1 = strlen(s);
    FOR (_, 0, q) {
        LL l, r; scanf("%lld%lld%s", &l, &r, s2);
        LL l2 = strlen(s2);
        LL ans = 0;
        if (l2 <= r - l + 1) {
            for (LL i = l; i + l2 - 1 <= r; ++i) {
                bool flag = true;
                FOR (j, 0, l2)
                    if (s2[j] != s[i + j]) { flag = false; break; }
                if (flag) ++ans;
            }
        }
        printf("%lld\n", ans);
    }
}
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <map>
using namespace std;

int main()
{
    char s[105] = { 0 };
    int q;
    int l, r;
    char z[105] = { 0 };
    scanf("%s", s);
    scanf("%d", &q);
    int i, j, k;
    for (i = 0; i < q; i++)
    {
        scanf("%d%d%s", &l, &r, z);
        int len = strlen(z);
        int flag = 0;
        for (j = l; j <= r - len+1; j++)
        {
            if (strncmp(s+j, z, len) == 0)
                flag++;
        }
        printf("%d\n", flag);
    }

    return 0;
}

my_code

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
char s[900],ss[200];
unsigned int h[2000],h2[200],base[200];
inline void init_hash(int l,char *s,unsigned int*h)
{
    h[0] = 0;
    for(int i=1;i<=l;i++)
        h[i] = h[i-1]*131+s[i-1];
    base[0] = 1;
    for(int i=1;i<=l;i++)
        base[i] = base[i-1]*131;
}
inline unsigned int str(unsigned int*h,int l,int r)
{
    return h[r]-h[l]*base[r-l];
}
int main()
{
    cin>>s;
    init_hash(200,s,h);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        int l,r;
        cin>>l>>r;
        unsigned int p1 = str(h,l,r);
       // cout<<p1<<endl;
        cin>>ss;
        int len = strlen(ss);
        init_hash(len,ss,h2);
        unsigned int p2 = str(h2,0,len);
        //cout<<p2<<endl;
        int sum = 0;
        for(int ii=l;ii<=r+1;ii++)
        {
            for(int j=ii+1;j<=r+1;j++)
            {
                     unsigned int p1 = str(h,ii,j);
                     if(p1==p2)sum++;
            }
        }
        cout<<sum<<endl;
    }

    return 0;
}

my_code2

#include <iostream>
#include <cstring>
using namespace std;
 int l,r,p,sum;
int next1[100000];
string s,z;
void gtnext()
{
    int k=-1,j=0;
    next1[0]=-1;
    while(j<z.size())
    {
        if(k==-1||z[j]==z[k])
        {
            j++;
            k++;
            if(z[j]!=z[k])
                next1[j]=k;
            else
                next1[j]=next1[k];
        }
        else
            k=next1[k];
    }
}
int kmp()
{
    int j=l,k=0;
    while(j<=r)
    {
        if(k==-1||s[j]==z[k])
        {
            j++;
            k++;
        }
        else
            k=next1[k];
    if(k==z.size())
       {
           sum++;
           k=next1[k];
       }
    }
    cout<<sum<<endl;
}
int main()
{
    cin>>s;
    cin>>p;

    for(int i=0;i<p;++i)
    {
        sum=0;
        cin>>l>>r;
        cin>>z;
        memset(next1,0,sizeof(next1));
        gtnext();
        kmp();
    }
    return 0;
}