• CF432D Prefixes and Suffixes


    CF432D Prefixes and Suffixes

    题意

    给你一个长度为n的长字符串,“完美子串”既是它的前缀也是它的后缀,求“完美子串”的个数且统计这些子串的在长字符串中出现的次数

    分析

    求出nex数组 , 在求出每个前缀出现的次数 , 从nex[n] 往下走就行了

    其实这道题是 , KMP 求每个前缀出现次数的模板题

    求前缀出现次数的写法

    	for(int i = 1 ; i <= n ; ++i) num[i]++;
    	for(int i = n ; i >= 1 ; --i) num[nex[i]] += num[i];
    

    这个的意思是 , 首先长度为 i 的前缀有大自己 , 也就是 1

    在考虑 长的为 i 的前缀可以把它的次数转移给谁呢?前缀本身已经计算过了, 接下来只要计算不是前缀本身的 , nex[i] 是他的最长公共前后缀,也就是有一个以 i 为右端点, 长为 nex[i] 的子串 和前缀相同 , 所以 i 出现多少次 , nex[i] 的前缀也应该加上他出现的次数

    	for(int i = 1 ; i <= n ; ++i) num[nex[i]]++;
    	for(int i = n ; i >= 1 ; --i) num[nex[i]] += num[i];
    	for(int i = 1 ; i <= n ; ++i) num[i]++;
    

    这个的意思是 , 先刨除他本身 ,再在最后加上;

    个人推荐第一种好理解 , 还短

    上本题代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N = 1e5+100;
    int n;
    int nex[N] , num[N] , cnt[N];
    char c[N];
    int main()
    {
    	scanf("%s",c+1); n = strlen(c+1);
    	for(int i = 2 , k = 0 ; i <= n ; ++i)
    	{
    		while(k && c[i] != c[k + 1]) k = nex[k];
    		if(c[i] == c[k + 1]) k++; nex[i] = k;
    	}
    	int tot = 0 , k = nex[n];
    	while(k) cnt[++tot] = k , k = nex[k];
    	printf("%d
    " , tot + 1);
    //	for(int i = 1 ; i <= n ; ++i) num[i]++;
    //	for(int i = n ; i >= 1 ; --i) num[nex[i]] += num[i];
    	
    	for(int i = 1 ; i <= n ; ++i) num[nex[i]]++;
    	for(int i = n ; i >= 1 ; --i) num[nex[i]] += num[i];
    	for(int i = 1 ; i <= n ; ++i) num[i]++;
    	for(int i = tot ; i >= 1 ; --i)
    		printf("%d %d
    " , cnt[i] , num[cnt[i]]);
    	printf("%d 1
    " , n);
    	return 0;
    }
    
  • 相关阅读:
    2.iptables规则管理
    十二.zabbix自动化添加主机
    ④.触发器
    ⑨.zabbix监控phpfpm
    动态dns
    ③.监控项
    十一.zabbix web监测
    ②.添加监控主机
    13.ansible get_url unarchive archive
    Planning in Factored State and Action Spaces with Learned Binarized Neural Network Transition Models
  • 原文地址:https://www.cnblogs.com/R-Q-R-Q/p/12141659.html
Copyright © 2020-2023  润新知