鬼题Ghost [manacher]
Posted H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了鬼题Ghost [manacher]相关的知识,希望对你有一定的参考价值。
本题目来自five20的周末考试题。
Description
给定一个 0/1 序列,求其中满足 " ? " 性质的子串个数。
" ? " 性质解释:
" ? " 性质的子串满足:将该子串先反转,再把每位上的数取反(即 0 变 1,1 变 0 )后得到的新串和原串相同。(举
例 : 1010 满足 " ? " 性质,因为先变为 0101 ,再取反为 1010 和原串相同)
Input Format
第一行只含一个 n ,表示 0/1 序列?度。
第二行为?度为 n 的 0/1 序列。
Output Format
一个数,表示 0/1 序列中满足 " ? " 性质的子序列个数(由于答案可能很大,对 233333333 取模)。
Sample
Input
7
1011001
Output
6
Explana on
样例中满足 " ? " 性质的 6 个子序列分别是: 2 个 10 ,2 个 01 ,1 个 1100 ,1 个 011001 。Subtasks
因为题目可能过于毒瘤,如果无法完全解决问题,可以尝试解决部分子任务。
测试点 N
1 N ≤ 1000
2 N ≤ 1000
3 N ≤ 1000
4 N ≤ 1000
5 N ≤ 10000
6 N ≤ 10000
7 N ≤ 10000
8 N ≤ 10000
9 N = 520520
10 N = 520520
11 N = 520520
12 N = 520520
13 N = 2333333
14 N = 2333333
15 N = 2333333
16 N = 2333333
17 N = 6666666
18 N = 6666666
19 N = 10000000
20 N = 10000000
分析:当时考试的时候还以为这是什么数位DP的问题(而且当时也没学manacher,也不太擅长字符串算法什么的),由于蒟蒻真的不擅长DP于是就打了个暴力水了25分,然后考完five20大佬说这是manacher算法题。然后今天学了一下manacher,A了这道题。实际上仔细分析这道题比一般的manacher还要简单一些,把判断条件改为不等,那么这样连中间的插入字符都不需要了,直接一个for循环套个manacher主体就过了。
Code:
1 //It is made by HolseLee on 30th Apr 2018 2 //five20‘s test 3 #include<bits/stdc++.h> 4 using namespace std; 5 const int mod=233333333; 6 const int N=1e7+7; 7 long long n,ans,p[N];char s[N]; 8 int main() 9 { 10 freopen("ghost.in","r",stdin); 11 freopen("ghost.out","w",stdout); 12 scanf("%lld%s",&n,s+1);long long id,mx=0; 13 for(int i=1;i<=n;i++){ 14 if(i<mx)p[i]=min(p[id*2-i],mx-i); 15 while(i+p[i]+1<=n&&i-p[i]>=1&&s[i+p[i]+1]!=s[i-p[i]])p[i]++; 16 if(p[i]+i>mx)id=i,mx=p[i]+i; 17 ans=(ans+p[i])%mod;} 18 printf("%lld",ans);return 0; 19 }
以上是关于鬼题Ghost [manacher]的主要内容,如果未能解决你的问题,请参考以下文章
FragmentTransaction.replace() 淡入过渡显示“幽灵”片段
Manacher || Luogu P3805模板manacher算法