前言:
妈耶,这道题写了一天,皇室我****
题目:
思路:
这题用二分+hash
先弄一个check函数,用来搞回文
然后二分。
CodeCodeCode(码风嘤嘤嘤):
#include <cstdio>
#include <iostream>
#define ll long long
using namespace std;
ll mid , r , l , sum , maxn , n , e ;
ll zo [5000001] , h1[5000001] , h2[5000001];
string str;
const ll INF = 233333;
void swap (int x, int y)//交换函数
{
int t;
t = x , x = y , y = t;
}
bool pd (ll l, ll r, ll m)//check搞回文
{
ll le,ri,hw1,hw2;
hw1 = l + m - 1;//左
hw2 = r + m - 1;//右
le = h1[hw1] - h1[l - 1];//回文
ri = h2[hw2] - h2[r - 1];
if (l > r)//如果l比r大
{
swap (le,ri);//交换
swap (l , r);
}
le *= zo[r - l];
return le == ri;//确保le == ri
}
int main()
{
scanf("%lld",&n);
cin>>str;
zo [0] = 1;
for (int i = 1; i <= n; ++i) zo[i] = zo[i - 1] * INF;
for (int i = 1; i <= n; ++i) h1[i] = h1[i - 1] + str[i - 1] * zo[i] ;
for (int i = 1; i <= n / 2; ++i) swap(str[i - 1],str[n - i]);//枚举中间
for (int i = 1; i <= n; ++i) if(str[i - 1] == '0') str[i - 1] = '1';else str[i - 1] = '0';
for (int i = 1; i <= n; ++i) h2[i] = h2[i - 1] + str[i - 1] * zo[i] ;
for (int i = 2; i <= n; ++i)
{
l = 1;
e = n - i + 2;
r = min(n - i + 1,n - e + 1);
maxn = 0;
while (l <= r)//二分模板
{
mid = (l + r) >> 1;
if(pd(i ,e ,mid))
{
maxn = max(maxn,mid);
l = mid + 1;
}
else r = mid - 1;
}
sum += maxn;
}
printf("%lld",sum);
return 0;
}