【二分】【hash】ANT-Antisymmetry(luogu P3501)

本文介绍了一种使用二分查找与哈希技术解决回文子串问题的方法,通过预处理字符串生成哈希值数组,利用二分查找优化搜索过程,实现了高效的回文子串匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言:

妈耶,这道题写了一天,皇室我****


题目:

在这里插入图片描述


思路:

这题用二分+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;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值