BZOJ 3473 字符串
思路
广义SAM的题目,先全部插入,然后每个字符串在SAM上匹配,如果发现当前sz小于k(就是前缀不满足条件),就跳fail(找前缀的后缀,就是找子串)到满足条件为止,然后一个满足条件的节点,它的所有parent Tree上的祖先也必定满足条件,所以一个满足条件的节点的贡献就是它的maxlen
ps:貌似求sz除了我这种,还可以set启发式合并
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <iostream>
#include <queue>
using namespace std;
int maxlen[201000],minlen[201000],trans[201000][26],suflink[201000],ans[201000],sz[201000],last[201000],endpos[201000],Nodecnt,n;
string s[101000];
int New_state(int _maxlen,int _minlen,int *_trans,int _sz,int _last,int _suflink){
    ++Nodecnt;
    maxlen[Nodecnt]=_maxlen;
    minlen[Nodecnt]=_minlen;
    if(_trans)
        for(int i=0;i<26;i++)
            trans[Nodecnt][i]=_trans[i];
    sz[Nodecnt]=_sz;
    last[Nodecnt]=_last;
    suflink[Nodecnt]=_suflink;
    return Nodecnt;
}
void update(int u,int x){
    while(u&&last[u]!=x){
        last[u]=x;
        sz[u]++;
        u=suflink[u];
    }
}
int add_len(int u,int c,int inq){
    if(trans[u][c]){
        int v=trans[u][c];
        if(maxlen[v]==maxlen[u]+1){
            update(v,inq);
            endpos[v]++;
            return v;
        }
        int y=New_state(maxlen[u]+1,0,trans[v],sz[v],last[v],suflink[v]);
        suflink[v]=y;
        minlen[v]=maxlen[y]+1;
        while(u&&trans[u][c]==v){
            trans[u][c]=y;
            u=suflink[u];
        }
        minlen[y]=maxlen[suflink[y]]+1;
        update(y,inq);
        return y;
    }
    else{
        int z=New_state(maxlen[u]+1,0,NULL,0,0,0);
        endpos[z]=1;
        while(u&&trans[u][c]==0){
            trans[u][c]=z;
            u=suflink[u];
        }
        if(!u){
            suflink[z]=1;
            minlen[z]=1;
            update(z,inq);
            return z;
        }
        int v=trans[u][c];
        if(maxlen[v]==maxlen[u]+1){
            suflink[z]=v;
            minlen[z]=maxlen[v]+1;
            update(z,inq);
            return z;
        }
        int y=New_state(maxlen[u]+1,0,trans[v],sz[v],last[v],suflink[v]);
        suflink[v]=suflink[z]=y;
        minlen[v]=minlen[z]=maxlen[y]+1;
        while(u&&(trans[u][c]==v)){
            trans[u][c]=y;
            u=suflink[u];
        }
        minlen[y]=maxlen[suflink[y]]+1;
        update(z,inq);
        return z;
    }
}
int k,in[200100];
queue<int> q;
int main(){
    freopen("test.in","r",stdin);
    freopen("test.out","w",stdout);
    Nodecnt=1;
    scanf("%d %d",&n,&k);
    for(int i=1;i<=n;i++){
        // scanf("%s",s+1);
        cin>>s[i];
        int last=1,len=s[i].length();
        // cout<<len<<endl;
        for(int j=0;j<len;j++)
            last=add_len(last,s[i][j]-'a',i);
    }
    for(int i=1;i<=n;i++){
        int lent=s[i].length(),p=1;
        // cout<<"!"<<lent<<endl;
        int ans=0;
        for(int j=0;j<lent;j++){
            p=trans[p][s[i][j]-'a'];
            while(sz[p]<k)
                p=suflink[p];
            if(p==0){
                p=1;
                continue;
            }
            ans+=(maxlen[p]);
        }
        printf("%d ",ans);
    }
    return 0;
}
BZOJ 3473 字符串的更多相关文章
- BZOJ 3277 串 & BZOJ 3473 字符串 (广义后缀自动机、时间复杂度分析、启发式合并、线段树合并、主席树)
		标签那么长是因为做法太多了... 题目链接: (bzoj 3277) https://www.lydsy.com/JudgeOnline/problem.php?id=3277 (bzoj 3473) ... 
- BZOJ 3473: 字符串 [广义后缀自动机]
		3473: 字符串 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 354 Solved: 160[Submit][Status][Discuss] ... 
- bzoj 3473 字符串 - 后缀数组 - 树状数组
		题目传送门 传送门 题目大意 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串 先用奇怪的字符把所有字符串连接起来. 建后缀树,数每个节点的子树内包含多少属 ... 
- bzoj 3277 串 && bzoj 3473 字符串 && bzoj 2780 [Spoj]8093 Sevenk Love Oimaster——广义后缀自动机
		题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3277 https://www.lydsy.com/JudgeOnline/problem.p ... 
- BZOJ 3277: 串/ BZOJ 3473: 字符串 ( 后缀数组 + RMQ + 二分 )
		CF原题(http://codeforces.com/blog/entry/4849, 204E), CF的解法是O(Nlog^2N)的..记某个字符串以第i位开头的字符串对答案的贡献f(i), 那么 ... 
- BZOJ 3473: 字符串 (广义后缀自动机)
		/* 广义后缀自动机, 每次加入维护 该right集合的set, 然后可以更新所有的parent,最终能够出现在k个串中right集合也就是set大小大于等于k的部分 这样的话就给了我们要跳的节点加了 ... 
- BZOJ 3473 字符串 ——广义后缀自动机
		这题就比较有趣了. 首先匹配一遍,然后统计子树叶子节点中包含大于等于k的节点个数(HH的项链) 然后就可以搞了. 关于合法的情况数,显然是l[i]-l[fa[i]],然后向下下传即可(YY一下). # ... 
- bzoj 3277: 串 & bzoj 3473: 字符串【后缀自动机||后缀数组】
		建一个广义后缀自动机(每加完一个串都返回root),在parent树上dpsum记录合法长度,打着时间戳往上跳,最后每个串在自动机上跑一变统计答案即可. 后缀数组理解起来可能方便一点,但是难写,就只说 ... 
- 【BZOJ 3473】 字符串 (后缀数组+RMQ+二分 | 广义SAM)
		3473: 字符串 Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串 ... 
随机推荐
- 2018-2019-2 20165225『网络对抗技术』Exp2:后门原理与实践
			2018-2019-2 20165225『网络对抗技术』Exp2:后门原理与实践 一.实验说明 任务一:使用netcat获取主机操作Shell,cron启动 (0.5分) 任务二:使用socat获取主 ... 
- Linux基础命令2
			1.修改网络状态: 1).Cd /etc/sysconfig/network-scripts/network-scripts 2).vi ifcfg-eth0 编辑 onboot=yes: 3 ... 
- 【mybatis】mybatis中 <if test=>等于的条件怎么写
- Acrobat Pro DC 2019 mac中文版(pdf编辑器)
			为大家准备了最新版本的Adobe Acrobat Pro DC 2019 for Mac,这是Adobe官方推出的pdf编辑器,acrobat pro dc 2019破解版可以轻松将扫描件.图像.网页 ... 
- 导出IndoorGML
			导出IndoorGML 
- vi检索
			/ :检索 n :向下执行上一步的检索 N :向上执行上一步的检索 
- 原生js 基于canvas写一个简单的前端 截图工具
			先看效果 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ... 
- git提交到一半关闭时
			一:出现问题 最近写东西,在提交代码时,突然出现一大推文件... 忘记加.gitignore文件了,导致所有的安装依赖也都上传了.所以,点击了关闭按钮,当下一次提交时,出现了错误. Another g ... 
- Summary: Calculate average where sum exceed double limits
			What is a good solution for calculating an average where the sum of all values exceeds a double's li ... 
- linux 笔记  第一天
			打开终端:ctrl+alt+t 清屏:ctrl+l 在终端在退出锁定:ctrl+c 目录:又称为文件夹,是包含所有的文件 目录创建规则: 1.大小是256 2.不能包含特殊字符 3.见名知义 路径:是 ... 
