CodeChef 3-Palindromes(Manacher)

3-Palindromes

Problem code: PALIN3

All submissions for this problem are available.

Read problems statements in Mandarin Chinese and Russian as well.

Mike likes strings. He is also interested in algorithms. A few days ago he discovered for himself a very nice problem:


You are given a digit string S. You need to count the number of substrings of S, which are palindromes.

Do you know how to solve it? Good. Mike will make the problem a little bit more difficult for you.


You are given a digit string S. You need to count the number of substrings of S, which are palindromes without leading zeros and can be divided by 3 without a remainder.

A string is a palindrome if it reads the same backward as forward. A
string is a palindrome without leading zeros if it reads the same
backward as forward and doesn‘t start with symbol ‘0‘. A string is a
digit string, if it doesn‘t contain any symbols except ‘0‘, ‘1‘, ‘2‘,
..., ‘9‘.

Please, note that you should consider string "0" as a palindrome without leading zeros.

Input

The first line of the input contains a digit string S.

Output

Your output should contain the only integer, denoting the number of substrings of S, which are palindromes without leading zeros and can be divided by 3 without a remainder.

Constraints

1 ≤ |S| ≤ 1 000 000

Example

Input:
1045003

Output:
4

Explanation

In the example you should count S[2..2] = "0", S[5..5] = "0", S[6..6] = "0" and S[7..7] = "3".

给出一个数字串。

问有多少个子串既是回文串也能被3整除~

先用Manacher处理好串的回文串长度。

然后用一个数组 cnt[i][j] 表示sigma( 1 ~  i-1 到i 的数 ) %3 == j 串的个数。

#include <bits/stdc++.h>

using namespace std;
typedef long long LL ;
typedef pair<LL,LL> pii;
#define X first
#define Y second
const int N = 2000010;
char Ma[N] , s[N];
int Mp[N] , len ;
void Manacher( char s[] , int len ) {
    int l = 0 ;
    Ma[l++] = ‘$‘ ; Ma[l++] = ‘#‘ ;
    for( int i = 0 ; i < len ; ++i ) {
        Ma[l++] = s[i];
        Ma[l++] = ‘#‘ ;
    }
    Ma[l] = 0 ; int mx = 0 , id = 0 ;
    for( int i = 0 ; i < l ; ++i ) {
        Mp[i] = mx>i?min(Mp[2*id-i],mx-i):1;
        while( Ma[i+Mp[i]] == Ma[i-Mp[i]] ) {
            Mp[i]++;
        }
        if( i + Mp[i] > mx ) {
             mx = i + Mp[i];
            id = i ;
        }
    }
}

bool is_dig( char op ) {
    if( op >= ‘0‘ && op <= ‘9‘ ) return true ;
    return false ;
}
LL cnt[N][3] , sum[N] ;

void Run() {
    int n = strlen(s) ;
    Manacher(s,n);
    len = 2 * n + 2 ;
    memset( sum , 0 , sizeof sum );
    memset( cnt , 0 , sizeof cnt );
    for( int i = 1 ; i < len ; ++i ){
           sum[i] = sum[i-1];
        if( is_dig(Ma[i]) ) sum[i] += ( Ma[i] - ‘0‘ );
    }
    for( int i = 2 ; i < len ; ++i ) {
        if( !is_dig(Ma[i]) || Ma[i] == ‘0‘ ) {
            for( int j = 0 ; j < 3 ; ++j )
                cnt[i][j] = cnt[i-1][j];
        }
        else {
            int x = Ma[i] - ‘0‘ ;
            for( int j = 0 ; j < 3 ; ++j ) {
                int _j = (j+x)%3;
                cnt[i][_j] += cnt[i-1][j] ;
            }
            cnt[i][x%3]++;
        }
    }
    LL ans = 0 ;
    for( int i = 2 ; i < len ; ++i ) {
        int x = 0 , tmp = sum[i-1] - sum[i-Mp[i]] ;
        if( is_dig(Ma[i]) ) {
            x = Ma[i] - ‘0‘ ;
            if( x % 3 == 0 ) ans++ ;
        }
        for( int j = 0 ; j < 3 ; ++j ) {
            if( ( 2*j + x )%3 == 0 ) {
                ans += cnt[i-1][j];
                for( int z = 0 ; z < 3 ; ++z ) if( (z+tmp)%3 == j ){
                    ans -= cnt[i-Mp[i]][z];
                }
            }
        }
    }
    printf("%lld\n",ans);
}

int main()
{
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif // LOCAL
    int _ , cas = 1 ;
    while( scanf("%s",s) != EOF )Run();
}

时间: 2024-08-24 23:42:30

CodeChef 3-Palindromes(Manacher)的相关文章

codechef Prime Palindromes 题解

给定一个数,求一个新数要大于等于这个数,而这个新数既要是palindromes回文又要是prime素数. 题目很简单,有人都使用取巧的方法保存好结果直接查表. 或者暴力法求解. 这里不使用保存表的方法,也不要用暴力法.- 这些方法都不好. 使用的技巧有: 1 而是使用next palindrome的技巧,只需要O(n),n是数位,可以认为是常数了. 2 判断素数的方法,时间效率是O(sqrt(n)), n是数值大小,如果是重复判断很多数是否是素数是有办法优化的,但是如果是单个素数判断的话,我还想

Petrozavodsk Winter-2013. Ural FU Contest Problem D. Five Palindromes manacher、一个串切割成5个回文子串、优化

Ural Federal University Contest, SKB Kontur Cup Petrozavodsk Winter Training Camp, Saturday, February 2, 2013 Problem D. Five Palindromes Input file: input.txt Output file: output.txt Time limit: 2 seconds (3 seconds for Java) Memory limit: 256 mebib

HDU 5340-Three Palindromes(Manacher算法)

题目地址:HDU 5340 题意:问是否能将字符串str分解为三段非空的回文串. 思路:我们根据Manacher算法对字符串进行处理,处理过程中产生的P数组,我们可以得到两个数组first和last. first存储的是第一个回文串的半径可能值. last存储的是第三个回文串的半径可能值. 根据first和last我们可以枚举第一个回文串和第三个回文串,然后根据半径找出第二个回文串的初始位置和结束位置.然后计算出第二个回文串的中点: 1.如果ll>rr,则第二个字符串的长度为负数,pass 2.

Hdu 5340 Three Palindromes 最大回文串 Manacher

Three Palindromes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 80    Accepted Submission(s): 21 Problem Description Can we divided a given string S into three nonempty palindromes? Input Fir

HDU 5340 Three Palindromes( 折半枚举+Manacher+记录区间 )

Three Palindromes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 809    Accepted Submission(s): 240 Problem Description Can we divided a given string S into three nonempty palindromes? Input F

HDU 5340——Three Palindromes——————【manacher处理回文串】

Three Palindromes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1244    Accepted Submission(s): 415 Problem Description Can we divided a given string S into three nonempty palindromes? Input F

Manacher BestCoder Round #49 ($) 1002 Three Palindromes

题目传送门 1 /* 2 Manacher:该算法能求最长回文串,思路时依据回文半径p数组找到第一个和第三个会文串,然后暴力枚举判断是否存在中间的回文串 3 另外,在原字符串没啥用时可以直接覆盖,省去一个数组空间,位运算 >>1 比 /2 速度快,用了程序跑快200ms左右,位运算大法好 4 */ 5 /************************************************ 6 Author :Running_Time 7 Created Time :2015-8-1

【SPOJ】NUMOFPAL - Number of Palindromes(Manacher,回文树)

[SPOJ]NUMOFPAL - Number of Palindromes(Manacher,回文树) 题面 洛谷 求一个串中包含几个回文串 题解 Manacher傻逼题 只是用回文树写写而已.. #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<

hdu5340—Three Palindromes—(Manacher算法)——回文子串

Three Palindromes Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1948    Accepted Submission(s): 687 Problem Description Can we divided a given string S into three nonempty palindromes? Input F