zoukankan      html  css  js  c++  java
  • bzoj3277: 串

    Description

    字符串是oi界常考的问题。现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中
    至少k个字符串的子串(注意包括本身)。

    Input

    第一行两个整数n,k。
    接下来n行每行一个字符串。
    n,k,l<=100000

    Output

    输出一行n个整数,第i个整数表示第i个字符串的答案。

    Sample Input

    3 1
    abc
    a
    ab

    Sample Output

    6 1 3

    Sol
    多个串可以建广义sam解决。
    每次加入新串时就把la=rt就行。
    全部建完后,从每个串的每个位置往上跳,统计每个点出现几次
    dp F[i] 表示i和i的后缀出现次数>=k的有几个。
    f[i]=f[par]+(num[i]>=k)?Max[par]-Max[i]:0;
    把串的每个前缀当成累加就行。
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<string>
    #define maxn 400005
    #define ll long long
    using namespace std;
    int n,m,rt=1,la=1,cnt=1;
    int tax[maxn],ord[maxn];
    ll f[maxn];
    char ch[maxn];string a[maxn];
    struct node{
        int Max,par,nex[26];
        int now,num;
    }s[maxn*2];
    
    void ins(int c){
        int np=++cnt,p=la;la=np;
        s[np].Max=s[p].Max+1;
        for(;p&&!s[p].nex[c];p=s[p].par)s[p].nex[c]=np;
        if(!p)s[np].par=rt;
        else {
            int q=s[p].nex[c];
            if(s[q].Max==s[p].Max+1)s[np].par=q;
            else {
                int nq=++cnt;
                s[nq].Max=s[p].Max+1;
                for(int i=0;i<26;i++)s[nq].nex[i]=s[q].nex[i];
                s[nq].par=s[q].par;
                s[q].par=s[np].par=nq;
                for(;s[p].nex[c]==q;p=s[p].par)s[p].nex[c]=nq;    
            }
        }
    }
    
    void Sort(){
        for(int i=1;i<=cnt;i++)tax[s[i].Max]++;
        for(int i=1;i<=cnt;i++)tax[i]+=tax[i-1];
        for(int i=1;i<=cnt;i++)ord[tax[s[i].Max]--]=i;
    }
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            scanf("%s",ch);
            a[i]=(string)ch;la=rt;
            for(int j=0;j<a[i].size();j++){
                ins(a[i][j]-'a');
            }
        }
        for(int i=1;i<=n;i++){
            int k=rt;
            for(int j=0;j<a[i].size();j++){
                k=s[k].nex[a[i][j]-'a'];
                int p=k;
                for(;s[p].now!=i&&p;p=s[p].par)s[p].num++,s[p].now=i;
            }
        }
        Sort();
        s[0].Max=0;
        for(int i=1;i<=cnt;i++){
            int k=ord[i];
            f[k]=f[s[k].par]+(s[k].num>=m?-s[s[k].par].Max+s[k].Max:0);
        }
        for(int i=1;i<=n;i++){
            ll ans=0;int k=rt;
            for(int j=0;j<a[i].size();j++){
                k=s[k].nex[a[i][j]-'a'];
                ans+=f[k];
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
    View Code
     
  • 相关阅读:
    XAMPP安装后启动Apache的Busy解决方法
    Win10 安装LoadRunner11遇到的问题及解决方案
    安装LoadRunner时提示缺少vc2005_sp1_with_atl_fix_redist解决方案
    Jmeter(十一)测试监听
    Jmeter(十)负载生成器
    session会话对象
    python enumarate方法的使用
    request 对于cookie,session, json的处理
    request 请求头的处理
    post请求中data参数的应用
  • 原文地址:https://www.cnblogs.com/liankewei/p/10666907.html
Copyright © 2011-2022 走看看