标签那么长是因为做法太多了。。。

题目链接: (bzoj 3277) https://www.lydsy.com/JudgeOnline/problem.php?id=3277

(bzoj 3473) https://www.lydsy.com/JudgeOnline/problem.php?id=3473

题解:

先讲三个做法公共部分: 建出广义SAM,然后对于每个点求出它在多少字符串中出现过。

做法一

把每个字符串在广义SAM上暴力跑。每跑到一个点就暴力沿着fail树往上跳,标记跳过的点,直到跳到已标记的点为止(每个串要换用不同的标记)。

时间复杂度\(O(L\sqrt L)\) (\(n\)为串的个数,\(L\)为总长度)

写一下时间复杂度分析: (我自己想的,很有可能是错的,有错恳请大佬指出!!感谢)

假设某个字符串长度为\(x\), 则最坏情况下它一直在往深处走,并且每一步都没有碰到已经跳过的点,这种情况下其走的步数是\(\sum^{x}_{i=1}i=O(x^2)\).

但是它还要受到另一个限制,就是走的步数不超过SAM总大小\(O(L)\). 因此其对时间复杂度贡献为\(O(\min(x^2),L)\).

计算最坏情况下的时间复杂度,也就是已知\(\sum^{m}_{i=1} x_i=L\), 求\(\sum^{m}_{i=1} \min(x_i^2,L)\)的最大值。显然当\(x_i>\sqrt L\)时是没有任何意义的(白白浪费代价,价值不增加),所以就是已知\(\sum^{m}_{i=1} x_i=L\)且对于任意\(i\)有\(i\le \sqrt L\), 求\(\sum^{m}_{i=1} x_i^2\)的最大值。由函数的凹凸性知显然(或者也可以用偏导数解释,如果你愿意的话。。。)所有串长均为\(\sqrt L\)时目标函数最大,为\(O(L\sqrt L)\).

做法二

类似于BZOJ2754/BZOJ2780, 就是个数颜色问题,每个点开个set记录经过这个点的所有串,然后沿着Parent树自下而上启发式合并。时间复杂度\(O(n\log^2n)\).

线段树合并貌似可以做到\(O(n\log n)\)?

做法三

依然是数颜色,可以使用DFS序+主席树等各种神奇做法解决。时间复杂度\(O(n\log^2n)\) (?)

代码

做法一

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<vector>
#define llong long long
using namespace std;const int N = 4e5;
const int S = 26;
struct SAM
{int id[N+3];int fa[N+3];int son[N+3][S+3];int len[N+3];int sz[N+3];int buc[N+3];int oid[N+3];int cnt[N+3];int cid[N+3];int mx[N+3];int siz,rtn,lstpos;void init() {id[0] = siz = rtn = lstpos = 1;}int insertstr(char ch){int p = lstpos,np; siz++; np = lstpos = siz; len[np] = len[p]+1; sz[np] = 1;for(; p && son[p][ch]==0; p=fa[p]) {son[p][ch] = np;}if(p==0) fa[np] = rtn;else{int q = son[p][ch];if(len[q]==len[p]+1) {fa[np] = q;}else{siz++; int nq = siz; len[nq] = len[p]+1;memcpy(son[nq],son[q],sizeof(son[q]));fa[nq] = fa[q]; fa[np] = fa[q] = nq;for(; p && son[p][ch]==q; p=fa[p]) {son[p][ch] = nq;}}}return np;}void getsort(){for(int i=1; i<=siz; i++) buc[len[i]]++;for(int i=1; i<=siz; i++) buc[i] += buc[i-1];for(int i=siz; i>=1; i--) oid[buc[len[i]]--] = i;}
} sam;
vector<char> str[N+3];
char a[N+3];
int n,m;int main()
{scanf("%d%d",&n,&m);sam.init();for(int i=1; i<=n; i++){scanf("%s",a+1);sam.lstpos = 1;int lena = strlen(a+1);for(int j=1; j<=lena; j++) {sam.insertstr(a[j]-96); str[i].push_back(a[j]);}}
//  for(int i=1; i<=sam.siz; i++) for(int j=1; j<=S; j++) if(sam.son[i][j]) printf("trans%d %d %d\n",i,j,sam.son[i][j]);
//  for(int i=1; i<=sam.siz; i++) printf("i%d len%d fa%d\n",i,sam.len[i],sam.fa[i]);sam.getsort();for(int i=1; i<=n; i++){int pos = sam.rtn;for(int j=0; j<str[i].size(); j++){pos = sam.son[pos][str[i][j]-96];int tmp = pos;for(; tmp && sam.cid[tmp]!=i; tmp=sam.fa[tmp]) {sam.cnt[tmp]++; sam.cid[tmp] = i;}}}sam.cnt[1] = 0;for(int i=1; i<=sam.siz; i++){int u = sam.oid[i];sam.mx[u] = sam.mx[sam.fa[u]]+(sam.cnt[u]>=m ? sam.len[u]-sam.len[sam.fa[u]] : 0);
//      printf("%d mx%d\n",u,sam.mx[u]);}for(int i=1; i<=n; i++){int pos = sam.rtn; llong ans = 0ll;for(int j=0; j<str[i].size(); j++){pos = sam.son[pos][str[i][j]-96];ans += (llong)sam.mx[pos];
//          putchar(str[i][j]); printf("pos%d\n",pos); puts("");}printf("%lld ",ans);}return 0;
}

BZOJ 3277 串 BZOJ 3473 字符串 (广义后缀自动机、时间复杂度分析)相关推荐

  1. BZOJ 3277 串 BZOJ 3473 字符串 (广义后缀自动机、时间复杂度分析、启发式合并、线段树合并、主席树)...

    标签那么长是因为做法太多了... 题目链接: (bzoj 3277) https://www.lydsy.com/JudgeOnline/problem.php?id=3277 (bzoj 3473) ...

  2. BZOJ.2780.[SPOJ8093]Sevenk Love Oimaster(广义后缀自动机)

    题目链接 \(Description\) 给定n个模式串,多次询问一个串在多少个模式串中出现过.(字符集为26个小写字母) \(Solution\) 对每个询问串进行匹配最终会达到一个节点,我们需要得 ...

  3. BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...

  4. BZOJ.3277.串(广义后缀自动机)

    题目链接 \(Description\) 给定n个串和K,求每个串中有多少个子串是这n个串中至少K个串的子串. \(Solution\) 同上题,我们可以算出每个节点所代表的串出现在了几个串中:而且我 ...

  5. bzoj 3277 串 后缀树+子树不同数个数

    题目大意 给定\(n\)个字符串和\(k\) 对于每个字符串,输出它有多少个子串至少是\(k\)个字符串的子串(包括自己) 分析 建出广义后缀自动机 至少是\(k\)个字符串的子串就是求子树内不同数个 ...

  6. bzoj 4566 找相同字符 —— 广义后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4566 建出两个串的广义后缀自动机: 统计每个点在两个串中出现次数的子树和,其实就是在两个串中 ...

  7. bzoj 3926: [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机)

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec   Memory Limit: 512 MB Submit: 1009   Solved: 596 [ Subm ...

  8. BZOJ3277 串 【广义后缀自动机】

    Description 字符串是oi界常考的问题.现在给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中 至少k个字符串的子串(注意包括本身). Input 第一行两个整数n, ...

  9. 【BZOJ3277】串(广义后缀自动机)

    Description 给定你n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串(包括本身). Solution 第200篇博客祭~ 建出广义后缀自动机,求出每个 ...

最新文章

  1. 九度oj 题目1411:转圈
  2. scrum敏捷项目管理工具leangoo卡片关联上线(可关联卡片,看板,项目)
  3. PV、UV、IP的区别
  4. 【spring-session】多项目实现session共享
  5. IBASE category 01 component hierarchy
  6. /usr/bin/ld: cannot find -l*** 这里***可以指lapack等
  7. Android 对话框黑色边框的解决
  8. 为什么 Eureka 比 ZooKeeper 更适合做注册中心?
  9. arcgis已试图对空几何执行该操作_ArcGIS中坐标转换和投影变换
  10. 跟踪某个类所创建对象的个数
  11. 北京远卓科技有限责任公司2017笔试题
  12. 【企业】走近华为,微观世界
  13. 电脑磁盘分区助手:DiskGenius磁盘管理与数据恢复软件
  14. 阿里巴巴罗汉堂聚6位诺贝尔奖得主研究社会问题丨科技在哪里强大,哪里便有更大的责任...
  15. 婚宴座位图html5,婚宴座位安排图 婚宴主桌安排示意图
  16. 微信看一看+视频下载方法
  17. 牧云Webshell检测神器
  18. SOT-23三极管、MOS管、LDO封装对应图汇总
  19. python 战舰_Python战舰:获取用户输入的他们想要多少艘战舰
  20. np.arange函数

热门文章

  1. 3DSlicer22:Module-ExtensionWizard Build Install
  2. VTK修炼之道71:交互与Widget_观察者/命令模式
  3. 写在中国雅虎关闭之后
  4. 禁用浏览器滚动条的解决方案
  5. 用delphi操作mapinfo
  6. 关键字 'USER' 附近有语法错误
  7. 网络分层模型OSI和TCP/IP四层模型
  8. Eclipse Tomcat调试timeout超时怎么办
  9. MFC(WTL)编辑框长度限制
  10. 引入sentinel后,json转化异常