博客
关于我
2021牛客寒假第四场 武辰延的字符串(二分+哈希)
阅读量:624 次
发布时间:2019-03-12

本文共 2021 字,大约阅读时间需要 6 分钟。

题目链接:

题目大意:

给出两个字符串 s s s t t t ,求有多少对 s s s 的非空前缀连起来是 t t t 的前缀

题目分析:

我们可以先枚举 t t t 的每一个位置
如果 s [ i ] ≠ t [ i ] s[i]\not=t[i] s[i]=t[i] 显然用 s s s 的前 i i i 个字符不可能凑成 t t t 的一个子串(因为 s [ i ] s[i] s[i] t [ i ] t[i] t[i] 不同)
如果 s [ i ] = t [ i ] s[i]=t[i] s[i]=t[i] 我们可以二分来找用 s . s u b s t r ( 1 , i ) s.substr(1,i) s.substr(1,i) 和其子串能构成 t t t 的子串的方案数,具体方法如下:
i i i s s s t t t 相同,之后再用哈希判断 s . s u b s t r ( 1 , i ) s.substr(1,i) s.substr(1,i) 的子串是否可以继续匹配,此题我使用了双哈希

具体细节见代码:

#include
#include
#include
#include
#include
#include
#include
#include
#define ll long long#define ull unsigned ll#define inf 0x3f3f3f3f#define Inf 0x3f3f3f3f3f3f3f3f//#define int llusing namespace std;int read(){ int res = 0,flag = 1; char ch = getchar(); while(ch<'0' || ch>'9') { if(ch == '-') flag = -1; ch = getchar(); } while(ch>='0' && ch<='9') { res = (res<<3)+(res<<1)+(ch^48);//res*10+ch-'0'; ch = getchar(); } return res*flag;}const int maxn = 1e5+5;const int mod = 1e9+7;const double pi = acos(-1);const double eps = 1e-8;const int base = 131;const int base2 = 233;int n,m,a[maxn<<2];char s[maxn],t[maxn];ull sum1[maxn],sum2[maxn],pre1[maxn],pre2[maxn],p[maxn],p2[maxn];pair
get_hash(int l,int r,ull a[],ull b[]){ return make_pair(a[r]-a[l-1]*p[r-l+1],(b[r]-b[l-1]*p2[r-l+1]%mod+mod)%mod);}signed main(){ scanf("%s%s",s+1,t+1); int len1 = strlen(s+1),len2 = strlen(t+1); p[0] = 1,p2[0] = 1; for(int i = 1;i <= max(len1,len2);i++) p[i] = p[i-1]*base,p2[i] = p2[i-1]*base2%mod; for(int i = 1;i <= len1;i++) sum1[i] = sum1[i-1]*base+s[i],pre1[i] = (pre1[i-1]*base2+s[i])%mod; for(int i = 1;i <= len2;i++) sum2[i] = sum2[i-1]*base+t[i],pre2[i] = (pre2[i-1]*base2+t[i])%mod; ll ans = 0; for(int i = 1;i <= min(len1,len2-1);i++) { if(s[i] != t[i]) break; int l = 0,r = len2-i,res = 0; while(r-l >= 0) { int mid = l+r>>1; if(get_hash(1,mid,sum1,pre1) == get_hash(i+1,i+mid,sum2,pre2)) l = mid+1,res = mid; else r = mid-1; } ans += res; } printf("%lld\n",ans); return 0;}

转载地址:http://frrxz.baihongyu.com/

你可能感兴趣的文章
Mysql 数据类型一日期
查看>>
MySQL 数据类型和属性
查看>>
mysql 敲错命令 想取消怎么办?
查看>>
Mysql 整形列的字节与存储范围
查看>>
mysql 断电数据损坏,无法启动
查看>>
MySQL 日期时间类型的选择
查看>>
Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
查看>>
MySQL 是如何加锁的?
查看>>
MySQL 是怎样运行的 - InnoDB数据页结构
查看>>
mysql 更新子表_mysql 在update中实现子查询的方式
查看>>
MySQL 有什么优点?
查看>>
mysql 权限整理记录
查看>>
mysql 权限登录问题:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)
查看>>
MYSQL 查看最大连接数和修改最大连接数
查看>>
MySQL 查看有哪些表
查看>>
mysql 查看锁_阿里/美团/字节面试官必问的Mysql锁机制,你真的明白吗
查看>>
MySql 查询以逗号分隔的字符串的方法(正则)
查看>>
MySQL 查询优化:提速查询效率的13大秘籍(避免使用SELECT 、分页查询的优化、合理使用连接、子查询的优化)(上)
查看>>
mysql 查询,正数降序排序,负数升序排序
查看>>
MySQL 树形结构 根据指定节点 获取其下属的所有子节点(包含路径上的枝干节点和叶子节点)...
查看>>