HDU 6194 string string string

HDU 6194

输入一个字符串,求出现K次得子串个数

我的做法是求出大于等于K次的子串个数-大于等于K+1次的子串个数

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <string>
#include <stdlib.h>
using namespace std;
typedef long long LL;
const int maxn = 1e5 + 10;
const int maxx = 127000;
struct Node {
    int pre, nxt[26];
    int step, number1, num;
    void Clear() {
        step = number1 = num = 0;
        pre = -1;
        memset(nxt, -1, sizeof(nxt));
    }
} st[maxn<<1];
int t, root, last, cur, k;
LL ans, tmp;
char str[maxn];

void init() {
    cur = 0;
    root = last = cur++;
    st[root].Clear();
}

void extend(int w) {
    int np = cur++, p = last;
    last = np;
    st[np].Clear();
    st[np].step = st[p].step+1;
    while(p != -1 && st[p].nxt[w] == -1)
        st[p].nxt[w] = np, p = st[p].pre;
    if(p == -1)
        st[np].pre = root;
    else {
        int q = st[p].nxt[w];
        if(st[q].step == st[p].step+1)
            st[np].pre = q;
        else {
            int nq = cur++;
            st[nq].Clear();
            st[nq].number1 = st[q].number1;
            st[nq].num = st[q].num;
            memcpy(st[nq].nxt, st[q].nxt, sizeof(st[q].nxt));
            st[nq].pre = st[q].pre;
            st[nq].step = st[p].step+1;
            st[np].pre = st[q].pre = nq;
            while(p != -1 && st[p].nxt[w] == q)
                st[p].nxt[w] = nq, p = st[p].pre;
        }
    }
    int f1 = 0, f2 = 0, pp = np;
    while(np!=-1 && (!f1 || !f2)){
        if(f1 == 0 && st[np].number1 < k) {
            st[np].number1++;
            if(st[np].number1 == k){
                ans+=(LL)st[np].step-st[st[np].pre].step;
                f1 = 1;
            }
        }
        if(f2 == 0 && st[np].num < k+1) {
            st[np].num++;
            if(st[np].num == k+1){
                tmp+=(LL)st[np].step-st[st[np].pre].step;
                f2 = 1;
            }
        }
        np = st[np].pre;
    }
}

void solve() {
    scanf("%d", &t);
    while(t--) {
        scanf("%d%s", &k, str);
        init();
        ans = tmp = 0;
        int len = strlen(str);
        for(int i = 0; i < len; i++)
            extend(str[i]-'a');
        printf("%lld\n", ans-tmp);
    }
}

int main() {
    solve();
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值