这还是一道数论题

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. LeetCode33—搜索旋转排序数组

    方法一:先找到旋转点,然后根据目标值重新确定二分查找区域. 时间复杂度:用到两次二分查找,每次二分查找粗略的认为是O(logn),那么时间复杂度为2 * O(logn): 空间复杂度:O(1). in ...

  2. webpack4 学习 --- 处理静态资源

    webpack 是利用loader 来处理各种资源的,wepback的配置基本上就是为各种资源文件,指定不同类型的loader. 1,处理css 最基本的css 处理loader 是css-loade ...

  3. confluence6.x安装

    一 简介 confluence是一个专业的企业知识管理与协同软件,可以用于构建企业wiki.通过它可以实现团队成员之间的协作和知识共享. 网上有关confluence的教程比较多,在此我们以confl ...

  4. 为知笔记Linux版编译使用记录

    本文档长期不定时更新,根据使用情况进行反馈. 目录 编译 Error creating SSL context 无法输入中文 如何打包使用 桌面图标 Markdown Windows 版本差异 常用快 ...

  5. KDJ计算公式

    计算方法编辑KDJ的计算比较复杂,首先要计算周期(n日.n周等)的RSV值,即未成熟随机指标值,然后再计算K值.D值.J值等.以n日KDJ数值的计算为例,其计算公式为n日RSV=(Cn-Ln)/(Hn ...

  6. 微信小程序地图控件篇 ---自定义图标被地图覆盖的问题

    今天在做微信小程序的时候遇到这个这样的问题  需要在地图上加个一个自定义的图标控件 类似这样的 刚开始的时候怎图片一直会被地图组件覆盖  ,要怎么解决这个问题  我去翻了下小程序的文档 有个cover ...

  7. RSA加密传输代码示例

    RSA加密传输代码示例 涉及敏感数据的传输,双方最好约定使用加密解密.那RSA非对称加密就大有作为了.服务端可以保留自己的私钥,发给客户端对应的公钥.这样就可以互相加解密了.php中rsa加解密实现: ...

  8. 基于jeesite的cms系统(六):Lucene全文搜索引擎

    1.lucene初始化 // @Value("${lucene.index.path}") private String indexPath = "/Users/vito ...

  9. VMware 常见问题及解决办法

    Ø  简介 本文介绍使用 VMware 虚拟机时常见的问题及解决办法,主要包括: 1.   虚拟机操作系统装好后,每次进入虚拟机还进入安装程序 2.   虚拟机不能与主机复制粘帖 3.   解决错误: ...

  10. 《11招玩转网络安全》之第五招:DVWA命令注入

    首先还是将DVWA的安全级别设置为Low,然后单击DVWA页面左侧的Command Injection按钮. ​ 图5-1  Low级别的命令注入 这个就是最典型的命令注入接口.在文本框中输入一个IP ...