鬼題Ghost [manacher]

  本題目來自five20的週末考試題。c++

  

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主體就過了。spa

  Code:code

 

//It is made by HolseLee on 30th Apr 2018
//five20's test
#include<bits/stdc++.h>
using namespace std;
const int mod=233333333;
const int N=1e7+7;
long long n,ans,p[N];char s[N];
int main()
{
  freopen("ghost.in","r",stdin);
  freopen("ghost.out","w",stdout);
  scanf("%lld%s",&n,s+1);long long id,mx=0;
  for(int i=1;i<=n;i++){
    if(i<mx)p[i]=min(p[id*2-i],mx-i);
    while(i+p[i]+1<=n&&i-p[i]>=1&&s[i+p[i]+1]!=s[i-p[i]])p[i]++;
    if(p[i]+i>mx)id=i,mx=p[i]+i;
    ans=(ans+p[i])%mod;}
  printf("%lld",ans);return 0;
}
相關文章
相關標籤/搜索