FJUT-这还是一道数论题
这还是一道数论题
最后来个字符串签个到吧,这题其实并不难,所需的算法比较基础,甚至你们最近还上过课。
为了降低难度,免得所有人爆零。这里给几个提示的关键字 :字符串,回文,二分,哈希. 注意要对奇偶回文分开二分
这样还不会做,说明基础有所欠缺。
给你一个字符串A和一个字符串B,请你求一个满足以下要求的所有字符串中,最长的字符串C的长度:
C必须同时是A和B的子串,即A和B中都必须存在一个子区间和C长得一样
C必须是一个回文,即正过来读和反过来读都一样
多组数据,请处理到EOF
每组数据包含,两行,每行都是仅由小写字符构成的字符串,代表A和B。
对于30%的数据。
保证|A|,|B|<=1000,且单个文件的字符总数小于10000
对于100%的数据
保证|A|,|B|<=100000,且单个文件的字符总数小于2e6
其中70%的数据答案为奇数哦
因为没有处理掉字符串尾巴上多余的'\r',所以为了防止读到'\r' 推荐使用scanf("%s");
输出C的长度
bbabbbcbcbbbddde
bbbabbbccadddbbba
dggdgzz
dggdbb
aaa
bbb
acbdbca
bcadacb
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-这还是一道数论题的更多相关文章
- FJUT3701 这也是一道数论题(线段树)题解
Problem Description 好久没出数据结构题,现在赶紧来做道数据结构题热热身 小q现在要去银行,他有个很厉害的bug能看到前面排队的人.假如当前有人正在办理业务,那么肯定要等待前一个人完 ...
- FJUT3703 这还是一道数论题(二分 + hash + manacher 或者 STL + hash 或者 后缀数组 + hash)题解
Problem Description 最后来个字符串签个到吧,这题其实并不难,所需的算法比较基础,甚至你们最近还上过课. 为了降低难度,免得所有人爆零.这里给几个提示的关键字 :字符串,回文,二分, ...
- fjutacm 3700 这是一道数论题 : dijkstra O(mlogn) 二进制分类 O(k) 总复杂度 O(k * m * logn)
/** problem: http://www.fjutacm.com/Problem.jsp?pid=3700 按二进制将k个待查点分类分别跑dijkstra **/ #include<std ...
- BZOJ 3209: 花神的数论题 [数位DP]
3209: 花神的数论题 题意:求\(1到n\le 10^{15}\)二进制1的个数的乘积,取模1e7+7 二进制最多50位,我们统计每种1的个数的数的个数,快速幂再乘起来就行了 裸数位DP..\(f ...
- 【洛谷】4317:花神的数论题【数位DP】
P4317 花神的数论题 题目背景 众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦. 题目描述 话说花神这天又来讲课了.课后照例有超级难的神题啦…… 我 ...
- 【LG4317】花神的数论题
[LG4317]花神的数论题 题面 洛谷 题解 设\(f_{i,up,tmp,d}\)表示当前在第\(i\)位,是否卡上界,有\(tmp\)个一,目标是几个一的方案数 最后将所有\(d\)固定,套数位 ...
- BZOJ3209 花神的数论题 【组合数学+数位DP+快速幂】*
BZOJ3209 花神的数论题 Description 背景 众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦. 描述 话说花神这天又来讲课了.课后照例有 ...
- [BZOJ3209]花神的数论题 组合数+快速幂
3209: 花神的数论题 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2498 Solved: 1129[Submit][Status][Disc ...
- 【BZOJ3209】花神的数论题 数位DP
[BZOJ3209]花神的数论题 Description 背景众所周知,花神多年来凭借无边的神力狂虐各大 OJ.OI.CF.TC …… 当然也包括 CH 啦.描述话说花神这天又来讲课了.课后照例有超级 ...
随机推荐
- JavaScript加载次序问题
3个文件,一个index.html如下 <!DOCTYPE html> <html> <head> <meta charset="UTF-8&quo ...
- 深入Redis持久化
转载:https://segmentfault.com/a/1190000017193732 一.Redis高可用概述 在介绍Redis高可用之前,先说明一下在Redis的语境中高可用的含义. 我们知 ...
- vue-cli全局安装
一.安装node.js a).不确定自己时候安装了node.js可以在控制台当中输入node -v来查看当前是否已经存在 如果看到输出了版本信息,那么证明已经有了node.js b).如果看到node ...
- springdata 一对多 级联操作 在注解里面开启级联操作@OneToMany(mappedBy = "customer",cascade = CascadeType.ALL)
- 【Linux】Linux主要目录以及说明
主要目录以及说明: /:根目录,位于Linux文件系统目录结构的顶层,一般根目录下只存放目录,不要存放文件,/etc./bin./dev./lib./sbin应该和根目录放置在一个分区中. /bin, ...
- Git源码管理工具使用
注明:双击tap键为自动补全操作 1.视频地址:http://www.newbieol.com/course/index_102.html 2.sourcetree是一个拥有界面的git工具吧 下载官 ...
- Flask 构建微电影视频网站(八)
评论收藏及弹幕 实现电影评论添加及列表.数据查询实现统计播放量和评论量.jquery ajax实现收藏电影,flask结合redis消息队列实现电影弹幕,bug处理等功能. 电影评论-统计 class ...
- PAT 甲级真题题解(1-62)
准备每天刷两题PAT真题.(一句话题解) 1001 A+B Format 模拟输出,注意格式 #include <cstdio> #include <cstring> #in ...
- 企业级playbook的使用
一.roles文件存放位置 可以在ansible.cfg配置文件中找到,默认路径如下: 也可以在ansible.cfg文件中自定义修改 二.下面以/usr/share/ansible目录来讲解 ans ...
- Mac 装机必备软件推荐
所谓Mac 装机必备软件,就是用 Mac OS X 几乎都要安装的软件,无论你是开发者.设计师还是摄影师,如果你是刚开始用 Mac,那么推荐看看以下内容,对你非常有帮助. 一.输入法 Mac 自带的中 ...