HDU 6194 string string string
来源:互联网 发布:css与js实现的小游戏 编辑:程序博客网 时间:2024/06/06 01:52
给出一个字符串求其出现恰好k次的子串数量
对串建立后缀自动机,所有right值为k的节点的value值的和就是答案.
可以在建自动机的时候把 每个前缀加一,然后拓扑更新到pre上,就可以统计每个节点出现的次数。然后val[u]-val[pre[u]]就是u节点子串个数。
#include <iostream>#include <cstdio>#include <string>#include <cstring>using namespace std;typedef long long LL;const int maxn = 2e5 + 10;int sum[maxn],temp[maxn];string s;struct SAM{ int ch[maxn][26], pre[maxn], val[maxn],cnt[maxn]; int last, tot; void init(){ last = tot = 0; memset(ch[0], -1, sizeof ch[0]); pre[0] = -1; val[0] = 0; } void extend(int c){ int p = last, np = ++tot; val[np] = val[p] + 1; memset(ch[np], -1, sizeof ch[np]); while(~p && ch[p][c] == -1) ch[p][c] = np, p = pre[p]; if(p == -1) pre[np] = 0; else{ int q = ch[p][c]; if(val[q] != val[p] + 1){ int nq = ++tot; memcpy(ch[nq], ch[q], sizeof ch[q]); val[nq] = val[p] + 1; pre[nq] = pre[q]; pre[q] = pre[np] = nq; while(~p && ch[p][c] == q) ch[p][c] = nq, p = pre[p]; } else pre[np] = q; } last = np; cnt[last]++; } void build(const string &s) { init(); int t=s.size()*2+10; for(int i=0;i<t;i++) cnt[i]=0; for(int i=0;i<s.size();i++) extend(s[i]-'a'); } void Tsort(const string &s,int k){ int t= s.size()*2+10; for(int i=0;i<t;i++) sum[i]=0; for (int i=0;i<=tot;i++) sum[val[i]]++ ; for (int i=1;i<=s.size();i++) sum[i]+=sum[i-1]; for (int i=0;i<=tot;i++) temp[sum[val[i]]--]=i; // for (int i=1;i<=tot+1;i++) printf("%d %d\n",temp[i],val[temp[i]]); ll ans=0; for(int i=tot+1;i>=2;i--) { int u=temp[i]; if(pre[u]>0) cnt[pre[u]]+=cnt[u]; if(cnt[u]==k) { ans+=val[u]-val[pre[u]]; } } printf("%lld\n",ans); } } sam;int main(){ ios::sync_with_stdio(false); cin.tie(0); int T,k; cin>>T; while(T--) { cin>>k>>s; sam.build(s); // sam.debug(); sam.Tsort(s,k); } return 0;}/* void debug() { for(int i = 0; i <= tot; ++i) { printf("id=%d, fa=%d, step=%d,son=[ ", i, pre[i], val[i]); for(int j = 0; j < 26; ++j) { if(ch[i][j]!=-1) printf("%c,%d ", j+'a',ch[i][j]); } printf("]"); printf(" cnt: %d\n",cnt[i]); } }*/
阅读全文
0 0
- HDU 6194 string string string
- HDU 6194 string string string
- HDU 6194 string string string
- HDU 6194 string string string
- HDU 6194string string string
- hdu 6194 string string string
- hdu 6194 string string string
- HDU 6194 string string string
- string string string HDU
- HDU 6194 string string string [后缀数组]
- HDU 6194 string string string【后缀数组】
- HDU 6194 string string string (SAM)
- String HDU
- string string string hdu 6194 (后缀数组做法)
- HDU 6194 string string string 后缀数组+lcp、Two Pointers
- HDU 6194 string string string 后缀数组+rmq
- hdu 6194 string string string 后缀数组+rmq+容斥
- string
- JavaBean规范
- 编写代码模拟手机与SIM卡的组合关系。
- [教程]Oracle VM VirtualBox 中添加共享文件夹
- linux下redis安装之HelloWorld
- Linux下的虚拟地址映射详解(一)逻辑地址到线性地址的映射
- HDU 6194 string string string
- 【观察】全面云化时代的探索和创新 神州数码定义中国云MSP之路
- opencv学习中——CvPoint、CvSize、CvRect、CV_RGB、cvRectangle
- 文章标题
- HDU 6003 Problem Buyer(鸽笼原理)
- 数据结构栈的基本的操作(C语言)
- 在web项目中使用mongoDB(一)
- Altium Designer画元器件封装三种方法
- LINUX(1)