Period II---fzu1901(Next数组)

题目链接:http://acm.fzu.edu.cn/problem.php?pid=1901

给你一个字符串 s 求出所有满足s[i] == s[i+p] ( 0 < i+p < len )的 p ;

kmp中Next[i] 表示前i个字符的前缀和后缀的最大匹配 s[0--x] == s[i-x-1 --- i] ;

下面是看别人的解释:

•知识点:KMP算法、对next数组的理解

•KMP算法中next数组的含义是什么?

•next数组:失配指针

•如果目标串的当前字符i在匹配到模式串的第j个字符时失配,那么我们可以让i试着去匹配next(j)

•对于模式串str,next数组的意义就是:

•如果next(j)=t,那么str[1…t]=str[len-t+1…len]

•我们考虑next(len),令t=next(len);

•next(len)有什么含义?

•str[1…t]=str[len-t+1…len]

•那么,长度为len-next(len)的前缀显然是符合题意的。

•接下来我们应该去考虑谁?

•t=next( next(len) );

•t=next( next (next(len) ) );

• 一直下去直到t=0,每个符合题意的前缀长是len-t

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
using namespace std;

const int N = 1e6+7;

char s[N];
int Next[N], ans[N];

void GetNext(char a[], int n)
{
    int i=0, j=-1;
    Next[0] = -1;
    while(i<n)
    {
        if(j==-1 || a[i]==a[j])
            Next[++i] = ++j;
        else
            j = Next[j];
    }
}

int main()
{
    int T, t=1, k, len;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%s", s);
        len = strlen(s);
        GetNext(s, len);
        k = 0;

        for(int j=len; j>0; j=Next[j])
            ans[k++] = len - Next[j];

        printf("Case #%d: %d\n", t++, k);
        for(int i=0; i<k; i++)
            printf("%d%c", ans[i], i==k-1?‘\n‘:‘ ‘);
    }
    return 0;
}

时间: 2024-10-14 13:21:10

Period II---fzu1901(Next数组)的相关文章

FZU 1901 Period II

Problem Description For each prefix with length P of a given string S,if S[i]=S[i+P] for i in [0..SIZE(S)-p-1], then the prefix is a “period” of S. We want to all the periodic prefixs. Input Input contains multiple cases. The first line contains an i

UVA 10869 - Brownie Points II(树状数组)

UVA 10869 - Brownie Points II 题目链接 题意:平面上n个点,两个人,第一个人先选一条经过点的垂直x轴的线,然后另一个人在这条线上穿过的点选一点作垂直该直线的线,然后划分出4个象限,第一个人得到分数为1,3象限,第二个人为二四象限,问第一个个人按最优取法,能得到最小分数的最大值,和这个值下另一个人的得分可能情况 思路:树状数组,可以枚举一点,如果能求出右上和左下点的个数就好办了,其实用一个树状数组,把y坐标离散化掉,然后记录进来,然后把点按x从左往右,每次删掉点后查询

POJ 2464 Brownie Points II 树状数组+扫描线

题意奇葩的一笔,本质上就是一个复杂统计,智商低下的我想不出来只好去搜了题解 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <queue> #include <deque> #inclu

LeetCode167 两数之和 II - 输入有序数组

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数. 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2. 说明: 返回的下标值(index1 和 index2)不是从零开始的. 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素. 示例: 输入: numbers = [2, 7, 11, 15], target = 9 输出: [1,2] 解释: 2 与 7 之和等于目标数 9 .因此 index1 = 1

HDOJ 5147 Sequence II 树状数组

树状数组: 维护每一个数前面比它小的数的个数,和这个数后面比他大的数的个数 再枚举每个位置组合一下 Sequence II Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 121    Accepted Submission(s): 58 Problem Description Long long ago, there is a seq

hdu 5147 Sequence II (树状数组 求逆序数)

题目链接 Sequence II Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 331    Accepted Submission(s): 151 Problem Description Long long ago, there is a sequence A with length n. All numbers in this se

lintcode 容易题:Merge Sorted Array II 合并排序数组 II

题目: 合并排序数组 II 合并两个排序的整数数组A和B变成一个新的数组. 样例 给出A = [1, 2, 3, empty, empty] B = [4,5] 合并之后A将变成[1,2,3,4,5] 注意 你可以假设A具有足够的空间(A数组的大小大于或等于m+n)去添加B中的元素. 解题: 这里给的是两个数组,上题给的是ArrayList格式,比较好处理,重新定义一个长度m+n的数组,太无节操,其他方法一时想不起来 官方解题,方法很技巧,可以倒着排序,这样就很简单了 Java程序: class

Q - Period II

For each prefix with length P of a given string S,if S[i]=S[i+P] for i in [0..SIZE(S)-p-1], then the prefix is a "period" of S. We want to all the periodic prefixs. Input Input contains multiple cases. The first line contains an integer T repres

hdu 5147 Sequence II(树状数组)

题目链接:hdu 5147 Sequence II 预处理每个位置作为b和c可以组成的对数,然后枚举b的位置计算. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 50005; int N, arr[maxn], fenw[maxn], lef[maxn], rig[maxn]; #d

[LintCode] Intersection of Two Arrays II 两个数组相交之二

Given two arrays, write a function to compute their intersection.Notice Each element in the result should appear as many times as it shows in both arrays.    The result can be in any order. Example Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [