福建工程学院第十四届ACM校赛J题题解
第六集,想不到你这个浓眉大眼的都叛变革命了
题意:
给你两个只包含01的字符串S和T,问你在允许一次错误的情况下,T是否能成为S的子串
思路:
这个问题的解法挺多,我是用fft匹配的,也比较简单,针对0和1匹配两次,第一次针对0就是把S串和T串中等于0的位置都标记成1,然后reverse一个串后进行fft,如果这两个位置都是0,就会出现1*1=1的情况,代表有一个位置匹配上了,0这样做一次,1这样做一次,他们的和就是匹配成功的次数,所以允许一次错误就是判断和是否大于len-1。
还有一个做法是指数哈希,判断两个串的哈希值的差是否是2^n,如果是的话check一下,就做出来了,2^n可以塞到hash或者map里。
还有exkmp等其他做法你们自行了解一下
代码实现
给出fft的做法(我只写了fft)
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = ;
ll a[N],b[N];
const ll PMOD=(<<)+;
const ll PR=;
static ll qp[];
ll res[N];
struct NTT__container
{
NTT__container()
{
int t,i;
for( i=; i<; i++)///注意循环上界与2n次幂上界相同
{
t=<<i;
qp[i]=quick_pow(PR,(PMOD-)/t);
}
}
ll quick_pow(ll x,ll n)
{
ll ans=;
while(n)
{
if(n&)
ans=ans*x%PMOD;
x=x*x%PMOD;
n>>=;
}
return ans;
}
int get_len(int n)///计算刚好比n大的2的N次幂
{
int i,len;
for(i=(<<); i; i>>=)
{
if(n&i)
{
len=(i<<);
break;
}
}
return len;
}
inline void NTT(ll F[],int len,int type)
{
int id=,h,j,k,t,i;
ll E,u,v;
for(i=,t=; i<len; i++)
{
if(i>t) swap(F[i],F[t]);
for(j=(len>>); (t^=j)<j; j>>=);
}
for( h=; h<=len; h<<=)
{
id++;
for( j=; j<len; j+=h)
{
E=;
for(int k=j; k<j+h/; k++)
{
u=F[k];
v=(E*F[k+h/])%PMOD;
F[k]=(u+v)%PMOD;
F[k+h/]=((u-v)%PMOD+PMOD)%PMOD;
E=(E*qp[id])%PMOD;
}
}
}
if(type==-)
{
int i;
ll inv;
for(i=; i<len/; i++)
swap(F[i],F[len-i]);
inv=quick_pow(len,PMOD-);
for( i=; i<len; i++)
F[i]=(F[i]%PMOD*inv)%PMOD;
}
}
inline void inv(ll *a,int len)///答案存在res中
{
if(len==)
{
res[]=quick_pow(a[],PMOD-);
return ;
}
inv(a,len>>);///递归
static ll temp[N];
memcpy(temp,a,sizeof(ll)*(len>>));
NTT(temp,len,);
NTT(res,len,);
int i;
for(i=; i<len; i++)
res[i]=res[i]*(-temp[i]*res[i]%PMOD+PMOD)%PMOD;
NTT(res,len,-);
memset(res+(len>>),,sizeof(ll)*(len>>));
}
void mul(ll x[],ll y[],int len)///答案存在x中
{
int i;
NTT(x,len,);///先映射到频域上
NTT(y,len,);///先映射到频域上
for(i=; i<len; i++)
x[i]=(x[i]*y[i])%PMOD;///在频域上点积
NTT(x,len,-);///再逆变换回时域
}
} cal;
ll x[N],y[N],z[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie();
int N;
cin>>N;
while(N--){
string s1,s2;
cin>>s1>>s2;
if(s2.length()>s1.length()){
puts("NO");
continue;
}
int len=cal.get_len(s1.length());
//做1匹配
memset(x,,len*sizeof(ll));
memset(y,,len*sizeof(ll));
memset(z,,len*sizeof(ll));
for(int i=;i<s1.length();i++){
x[i]=s1[i]-'';
}
for(int i=;i<s2.length();i++){
y[i]=s2[i]-'';
}
reverse(y,y+s2.length());
cal.mul(x,y,len);
//for(int i=0;i<len;i++)
for(int i=s2.length()-;i<s1.length();i++)
z[i]+=x[i];
//做0匹配
memset(x,,len*sizeof(ll));
memset(y,,len*sizeof(ll));
for(int i=;i<s1.length();i++){
x[i]=-(s1[i]-'');
}
for(int i=;i<s2.length();i++){
y[i]=-(s2[i]-'');
}
reverse(y,y+s2.length());
cal.mul(x,y,len);
//for(int i=0;i<len;i++)
for(int i=s2.length()-;i<s1.length();i++)
z[i]+=x[i];
bool flag=;
for(int i=s2.length()-;i<s1.length();i++){
if(z[i]>=s2.length()-){
flag=;
break;
}
}
if(flag){
puts("YES");
}
else {
puts("NO");
}
}
}
福建工程学院第十四届ACM校赛J题题解的更多相关文章
- 福建工程学院第十四届ACM校赛M题题解 fwt进阶,手推三进制fwt
第九集,结束亦是开始 题意: 大致意思就是给你n个3进制的数字,让你计算有多少对数字的哈夫曼距离等于i(0<=i<=2^m) 思路: 这个是一个防ak题,做法是要手推公式的fwt 大概就这 ...
- 福建工程学院第十四届ACM校赛G题题解
外传:编剧说了不玩游戏不行 题意: 有n个石堆,我每次只能从某一堆中取偶数个石子,你取奇数个,我先手,先不能操作的人输.问最后谁能赢. 思路: 这个题仔细想想,就发现,取奇数的人有巨大的优势,因为假设 ...
- 福建工程学院第十四届ACM校赛B题题解
第二集,未来的我发量这么捉急的吗 题意: 有n个数,请问有多少对数字(i,j)(1<=i<j<=n),满足(a[i]^a[j])+((a[i]&a[j])<<1) ...
- 福建工程学院第十四届ACM程序设计大赛 - E - 外传:小晋逃生记
http://www.fjutacm.com/Contest.jsp?cid=705#P4 其实想清楚了就很简单,之前想了很多种方法,以为是二分什么的,看起来就像是一个单峰函数.但是发现直接暴力一波就 ...
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- 湖南大学第十四届ACM程序设计新生杯(重现赛)G a+b+c+d=? (16进制与LL范围)
链接:https://ac.nowcoder.com/acm/contest/338/G来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 32768K,其他语言65536K6 ...
- 湖南大学第十四届ACM程序设计新生杯(重现赛)I:II play with GG(博弈论||DP)
链接:https://ac.nowcoder.com/acm/contest/338/I 来源:牛客网 题目描述 IG won the S championship and many people a ...
- 湖南大学第十四届ACM程序设计新生杯(重现赛)
RANK 0 题数 0 期末复习没有参加,补几道喜欢的题. A: AFei Loves Magic 签到 思路 :不需考虑 碰撞 直接计算最终状态即可. #include<bits/stdc ...
- 湖南大学第十四届ACM程序设计新生杯 E.Easy Problem
E.Easy Problem Description: Zghh likes number, but he doesn't like writing problem description. So h ...
随机推荐
- 设置object的key为变量
https://blog.csdn.net/shu580231/article/details/81367271
- ASIHTTPRequest使用
http://qk13warcraft.blog.163.com/blog/static/157549344201271633014969/ 1.创建和运行请求 创建一个同步请求 这是最简单的用法,发 ...
- JAVA中随机生成确定范围内的随机数
最近工作中的一个业务需要再确定范围内取出一个随机数,网上到时搜出来一堆可以实现的方法,但是鄙人仍是理解不了,虽说已经copy方法直接完成工作了.今天抽时间整理下,希望能够帮助大家更好的理解随机数的实现 ...
- 20175215 2018-2019-2 第十周java课程学习总结
第十二章 Java多线程机制 12.1 进程与线程 12.1.1 操作系统与进程 程序是一段静态的代码,它是应用软件执行的蓝本. 进程是程序的一次动态执行过程,它对应了从代码加载.执行至执行完毕的一个 ...
- vuex 讲解
vuex 状态的管理状态,它采用集中式存储管理应用的所有组件的状态,尤其是在中大型项目,则是很好的开发利器 vuex 的流程图 vuex 的优势: 1. vuex 的存储状态,响应式的 2. 他是所有 ...
- Python做域用户验证登录
安装包 ldap3 代码: from ldap3 import Server, Connection, ALL, NTLM # 连接 server = Server('public.ad.com', ...
- Cortex-M3 R0~R15寄存器组 & 特殊功能寄存器组
[R0~R15寄存器组] Cortex-M3处理器拥有R0~R15的寄存器组,如: [R0~R12通用寄存器]R0~R12都是32位通用寄存器,用于数据操作.其中: R0~R7为低组寄存器,所有的指令 ...
- JAVA向C传递数据
传递数组 数组是个对象,传递对象就是传递地址,修改地址上的值,数组的内容就会改变 //获取数组首地址 int* p = (*env)->GetIntArrayElements(env, arra ...
- AndroidManifest.xml中的<uses-feature>以及和<uses-permission>之间的联系
概述:<uses-feature>用来声明应用中需要用的硬件和软件的功能. 硬件特性:表明您的应用需要用的硬件功能. 功能类型 特征描述 描述 音频 android.hardware.au ...
- java:solr
1.solr(数据导入solr自带数据库): ImportItemController.java: package com.solr.controller; import org.springfr ...