这还是一道数论题

TimeLimit:4000MS  MemoryLimit:128MB
64-bit integer IO format:%lld
Special Judge
 
Problem Description

最后来个字符串签个到吧,这题其实并不难,所需的算法比较基础,甚至你们最近还上过课。

为了降低难度,免得所有人爆零。这里给几个提示的关键字 :字符串,回文,二分,哈希. 注意要对奇偶回文分开二分

这样还不会做,说明基础有所欠缺。

给你一个字符串A和一个字符串B,请你求一个满足以下要求的所有字符串中,最长的字符串C的长度:

  1. C必须同时是A和B的子串,即A和B中都必须存在一个子区间和C长得一样

  2. C必须是一个回文,即正过来读和反过来读都一样

Input

多组数据,请处理到EOF

每组数据包含,两行,每行都是仅由小写字符构成的字符串,代表A和B。

对于30%的数据。

保证|A|,|B|<=1000,且单个文件的字符总数小于10000

对于100%的数据

保证|A|,|B|<=100000,且单个文件的字符总数小于2e6

其中70%的数据答案为奇数哦

因为没有处理掉字符串尾巴上多余的'\r',所以为了防止读到'\r' 推荐使用scanf("%s");

Output

输出C的长度

SampleInput
bbabbbcbcbbbddde
bbbabbbccadddbbba
dggdgzz
dggdbb
aaa
bbb
acbdbca
bcadacb
SampleOutput
5
4
0
1
hint:
对于第一个数据C取bbabb
对于第二个数据C取dggd 用马拉车预处理,这样可以O(1)判断任意区间是否是回文。 然后就是用二分答案的长度,用哈希O(n)计算是否有长度为len的公
共回文子串,注意。  二分时奇偶回文要分开二分。因为如何有2k+2长度的公共回文。肯定也会有2k长度的公共回文,但是不保证也
有2k+1的长度的公共回文。。数据里70%的答案是奇的。所以你只二分奇数长度即可得到70分. 如果不想奇偶分开讨论的话,可以用马拉车的技巧,转化为全部都是奇回文
细节在代码中有解释
#include<bits/stdc++.h>
typedef unsigned long long ull;
const int maxn=100005;
const ull P=131;
using namespace std;
char str1[maxn],str2[maxn];
ull f1[maxn],f2[maxn],p[maxn];
int len1,len2,tmp_len;
int len[maxn<<1];
char tmp[maxn<<1];
void init()
{
p[0]=1;
for(int i=1; i<maxn; i++)
{
p[i]=p[i-1]*P;
}
}
ull Hash(ull f[],int l,int r)
{
return f[r+1]-f[l]*p[r-l+1];
} void GetHash(char str[],ull f[])
{
int len_str=strlen(str);
f[0]=0;
for(int i=0; i<len_str; i++)
f[i+1]=f[i]*P+str[i];
}
int manachar_init(char st[])
{
int i,str_len=strlen(st);
tmp[0]='@';///加一个特殊字符,防止越界
for(int i = 1; i <= 2*str_len ; i+=2)
{
tmp[i]='#';
tmp[i+1]=st[i/2];
}
tmp[2*str_len+1]='#';
tmp[2*str_len+2]='$';///字符串结尾加一个字符,防止越界
return 2*str_len+1;///返回转换字符串的长度
}
void manachar(char st[],int str_len)
{
int p_mx=0,ans=0,po=0;///p_mx即为“当前”计算回文串最右边字符的最大值,po为当前该回文字符串的中心
for(int i=1;i<=str_len;i++)
{
if(i<p_mx)
len[i]=min(p_mx-i,len[2*po-i]);///po对应最大回文子串中心点的位置
else
len[i]=1;
while(st[i-len[i]]==st[i+len[i]])
len[i]++;
if(len[i]+i>p_mx)
{
po=i;
p_mx=i+len[i];
}
ans=max(ans,len[i]);
}
}
map< ull,int >mp;
bool cheak(int m)
{
mp.clear();
for(int i=0; str1[i+m-1]; i++)
{
if(len[i+i+m+1]-1>=m)///i+i+m+1对应原回文子字符串str[i~(i+m-1)]在转换后字符串的回文中心位置(l+r+2)
{
ull cnt=Hash(f1,i,i+m-1);
mp[cnt]=i;///记录该回文串的起点
}
}
for(int i=0; str2[i+m-1]; i++) ///枚举第二个字符串的起点
{
ull cnt=Hash(f2,i,i+m-1);
if(mp.count(cnt))
{
int po=mp[cnt];///po为在str1中的起点
int j=0;
for( j=0; j<m; j++)///判断这两个字符串是否相等
{
if(str1[po+j]!=str2[i+j])
break;
}
if(j>=m)
return true;
}
}
return false;
}
int main()
{
init();
while(scanf("%s %s",str1,str2)!=EOF)
{
int ans=0;
GetHash(str1,f1);
GetHash(str2,f2);
len1=strlen(str1);
len2=strlen(str2);
tmp_len=manachar_init(str1);
///tmp为转换后的字符串 tmp_len该字符串长度
manachar(tmp,tmp_len);
int l=0,r=min(len1,len2)/2+1;
while(l+1<r)
{
int mid=(l+r)/2;
if(cheak(mid*2))
{
l=mid;
}
else
{
r=mid;
}
}
ans=max(ans,l*2);
l=l-1,r=min(len1,len2)/2+1;
while(l+1<r)
{
int mid=(l+r)/2;
if(cheak(mid*2+1))
{
l=mid;
}
else
{
r=mid;
}
}
ans=max(ans,l*2+1);
printf("%d\n",ans);
}
return 0;
}

  


FJUT-这还是一道数论题的更多相关文章

  1. FJUT3701 这也是一道数论题(线段树)题解

    Problem Description 好久没出数据结构题,现在赶紧来做道数据结构题热热身 小q现在要去银行,他有个很厉害的bug能看到前面排队的人.假如当前有人正在办理业务,那么肯定要等待前一个人完 ...

  2. FJUT3703 这还是一道数论题(二分 + hash + manacher 或者 STL + hash 或者 后缀数组 + hash)题解

    Problem Description 最后来个字符串签个到吧,这题其实并不难,所需的算法比较基础,甚至你们最近还上过课. 为了降低难度,免得所有人爆零.这里给几个提示的关键字 :字符串,回文,二分, ...

  3. fjutacm 3700 这是一道数论题 : dijkstra O(mlogn) 二进制分类 O(k) 总复杂度 O(k * m * logn)

    /** problem: http://www.fjutacm.com/Problem.jsp?pid=3700 按二进制将k个待查点分类分别跑dijkstra **/ #include<std ...

  4. BZOJ 3209: 花神的数论题 [数位DP]

    3209: 花神的数论题 题意:求\(1到n\le 10^{15}\)二进制1的个数的乘积,取模1e7+7 二进制最多50位,我们统计每种1的个数的数的个数,快速幂再乘起来就行了 裸数位DP..\(f ...

  5. 【洛谷】4317:花神的数论题【数位DP】

    P4317 花神的数论题 题目背景 众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦. 题目描述 话说花神这天又来讲课了.课后照例有超级难的神题啦…… 我 ...

  6. 【LG4317】花神的数论题

    [LG4317]花神的数论题 题面 洛谷 题解 设\(f_{i,up,tmp,d}\)表示当前在第\(i\)位,是否卡上界,有\(tmp\)个一,目标是几个一的方案数 最后将所有\(d\)固定,套数位 ...

  7. BZOJ3209 花神的数论题 【组合数学+数位DP+快速幂】*

    BZOJ3209 花神的数论题 Description 背景 众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦. 描述 话说花神这天又来讲课了.课后照例有 ...

  8. [BZOJ3209]花神的数论题 组合数+快速幂

    3209: 花神的数论题 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2498  Solved: 1129[Submit][Status][Disc ...

  9. 【BZOJ3209】花神的数论题 数位DP

    [BZOJ3209]花神的数论题 Description 背景众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦.描述话说花神这天又来讲课了.课后照例有超级 ...

随机推荐

  1. pstree:command not found

    centos7默认并没有安装pstree,所以会有pstree:command not found yum -y install psmisc

  2. c提高第六次课 文件读取

    一.基本概念1.文件分类 普通文件:存放在硬盘中的文件 设备文件:屏幕.键盘等特殊文件 文本文件:ASCII文件,每个字节存放一个字符的ASCII码,打开文件看到的是文本信息 二进制文件:数据按其在内 ...

  3. 使用pycharm进行远程开发部署调试设置 与 远程部署调试是否必须使用远程主机的解释器?

    远程开发部署调试目的: 配置pycharm远程部署调试主要用于本地代码与远程服务器上的代码进行同步,使得本地代码经过修改后,可以很容易的同步到远程服务器上.同时设置pycharm的解释器为远程服务器的 ...

  4. springcloud 设置feign超时时间

    转载网址:http://www.pianshen.com/article/187038775/

  5. 内部yum仓库制作

    有些安装收到网络隔离(申请一个到DMZ区的通行证很困难) 使用yum的命令工具,在有网络环境下同步我们的yum仓库,并用http服务器代理和制作repo源进行内部安装. 实操: [root@maste ...

  6. METO CODE 223 拉力赛

    传送门 继续水板子题... #include <bits/stdc++.h> #define ll long long using namespace std; inline int re ...

  7. leanote使用本地账户时,去掉待同步的小红点

    切换开发者工具,如下图,点击左上角的箭头图标,选取元素,直接选择小红点. 然后会看到小红点来自于resources/app/public/themes/default.css文件中2092行: .it ...

  8. Lending Club—构建贷款违约预测模型

    python信用评分卡(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_camp ...

  9. 04-oracle中的视图

    1.创建视图 介绍: 视图(View)通过SELECT查询语句定义,它是从一个或多个表(或视图)导出的,用来导出视图的表称为基表(Base Table),导出的视图称为虚表.在数据库中,只存储视图的定 ...

  10. 关于 Microsoft Dynamics CRM has encountered an error 弹窗的问题

    最近用 IE 测试 CRM 网站的时候发现一个问题:时不时会弹出“Microsoft Dynamics CRM has encountered an error”的小框框,而且还不是在特定位置才会弹出 ...