SPOJ
来源:互联网 发布:管家婆远程桌面该软件 编辑:程序博客网 时间:2024/06/09 20:18
SPOJ - NSUBSTR
给定字符串S,求长度为K的子串,最多出现多少次。
后缀自动机+拓扑排序+DP
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>#include <bitset>#define INF 0x3f3f3f3f#define eps 1e-6#define PI 3.1415926#define mod 1000000009#define base 2333using namespace std;typedef long long LL;const int maxn = 3e5 + 10;const int maxx = 1e3 + 10;inline void splay(int &v) { v=0;char c=0;int p=1; while(c<'0' || c >'9'){if(c=='-')p=-1;c=getchar();} while(c>='0' && c<='9'){v=(v<<3)+(v<<1)+c-'0';c=getchar();} v*=p;}struct Node { Node *pre, *nxt[26]; int step, v; void Clear() { step = 0, v = 0; pre = NULL; memset(nxt, NULL, sizeof(nxt)); }} *root, *last;Node st[maxn<<1], *top[maxn<<1], *cur;char str[maxn];int cnt[maxn], dp[maxn];void init() { cur = st; root = last = cur++; root->Clear();}void extend(int w) { Node *np = cur++, *p = last; np->Clear(); np->step = p->step+1; while(p && !p->nxt[w]) p->nxt[w] = np, p = p->pre; if(p == NULL) np->pre = root; else { Node *q = p->nxt[w]; if(q->step == p->step+1) np->pre = q; else { Node *nq = cur++; nq->Clear(); memcpy(nq->nxt, q->nxt, sizeof(q->nxt)); nq->step = p->step+1; nq->pre = q->pre; np->pre = q->pre = nq; while(p && p->nxt[w] == q) p->nxt[w] = nq, p = p->pre; } } last = np;}void solve() { while(scanf("%s", str) != EOF) { init(); int len = strlen(str); for(int i = 0; i < len; i++) extend(str[i]-'a'); memset(cnt, 0, sizeof(cnt)); memset(dp, 0, sizeof(dp)); for(Node *p = st; p != cur; p++) cnt[p->step]++; for(int i = 1; i <= len; i++) cnt[i] += cnt[i-1]; for(Node *p = st; p != cur; p++) top[--cnt[p->step]] = p; for(int i = 0; i < len; i++) { root = root->nxt[str[i]-'a']; root->v = 1; } int num = cur-st; for(int i = num-1; i > 0; i--) { dp[top[i]->step] = max(dp[top[i]->step], top[i]->v); if(top[i]->pre) top[i]->pre->v += top[i]->v; } for(int i = len-1; i >= 0; i--) dp[i] = max(dp[i], dp[i+1]); for(int i = 1; i <= len; i++) printf("%d\n", dp[i]); }}int main() { //srand(time(NULL)); //freopen("kingdom.in","r",stdin); //freopen("kingdom.out","w",stdout); solve();}
阅读全文
1 0
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- Egret 之 消除游戏 开发 PART 6 Egret elimination game development PART 6
- [UVa 11093] 环形跑道(Just Finish it up)
- 天易48----Springmvc结合rabbitmq简单示例
- 第5章 继承
- python的两种不同print print , 加逗号和print "%s %s" 不一样
- SPOJ
- JavaWeb学习总结(一)——JavaWeb开发入门
- 我的博客
- Unity3D 入门 游戏开发 Unity3D portal game development
- Android 2017你该用到的开源框架
- Python简单爬虫
- 解题报告:HDU_4947:GCD Array 莫比乌斯反演+树状数组
- Python 函数参数
- 转贴一篇经典文章--条件判定覆盖和修正条件判定覆盖的差异