zoukankan      html  css  js  c++  java
  • CodeForces 432D Prefixes and Suffixes

    题目

    传送门

    解法

    容易想到用 \(\mathtt {kmp}\)

    第一个答案就是从 \(n\) 开始往前找 \(nxt\) 并记录。

    第二个答案其实也很简单:我们用 \(nxt\) 来做一个 \(\mathtt{dp}\)。先给所有前缀 \(\mathtt{dp}\) 值赋为 \(1\),再从大到小枚举前缀,将此前缀的出现次数贡献到它最长 \(\rm border\)\(\mathtt{dp}\) 值上,容易发现这是不重不漏的。

    代码

    #include<cstdio>
    #include<cstring>
    
    const int N = 1e5 + 2;
    
    char s[N];
    int nxt[N], n, p[N], cnt[N], m;
    
    int read() {
    	int x = 0, f = 1; char s;
    	while((s = getchar()) > '9' || s < '0') {if(s == '-') f = -1;}
    	while(s <= '9' && s >= '0') {
    		x = (x << 1) + (x << 3) + (s ^ 48);
    		s = getchar();
    	}
    	return x * f;
    }
    
    void getNxt() {
    	int j = 0;
    	for(int i = 2; i <= n; ++ i) {
    		while(j && s[i] != s[j + 1]) j = nxt[j];
    		if(s[i] == s[j + 1]) ++ j;
    		nxt[i] = j;
    	}
    }
    
    int main() {
    	scanf("%s", s + 1); n = strlen(s + 1);
    	getNxt();
    	int pos = n;
    	while(pos) {
    		p[++ m] = pos;
    		pos = nxt[pos];
    	}
    	for(int i = 1; i <= n; ++ i) cnt[i] = 1;
    	for(int i = n; i >= 1; -- i) cnt[nxt[i]] += cnt[i];
    	printf("%d\n", m);
    	for(int i = m; i >= 1; -- i) printf("%d %d\n", p[i], cnt[p[i]]);
    	return 0;
    }
    
  • 相关阅读:
    leveldb的搜索
    分布式存储bfs
    golang channel的行为
    支持rotate和大小限制的golang log库
    后台架构 一些需要注意的地方
    不要滥用面向对象,写出难以阅读和修改的代码
    goloader
    逻辑引擎、工作流、CMDB小感
    HTML5学习笔记4
    HTML5学习笔记3
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/12341693.html
Copyright © 2011-2022 走看看