题意

给出\(n\)个01字节和\(m\)个01字节,要求用后者去匹配前者,两个串能匹配当且仅当除了每个字节末位不同,其他位都要相同。问匹配后者至少有多少个末位不同。(\(1 \le m \le n \le 2.5 \times 10^5\))

分析

首先我们可以用kmp计算出能匹配的位置,然后单独考虑末位不同的情况。

题解

我们将末尾的位提取出来,则考虑\(n\)个\(01\)位和\(m\)个\(01\)位。对于模板串的\(01\)位,我们需要计算以这个位置结束与匹配串位相同的数目,发现其实我们将匹配串反转,然后就是卷积!于是我们就可以用fft做了。

#include <bits/stdc++.h>
using namespace std;
const double pi=acos(-1);
const int N=2.5e5+10, nS=N*8, Lim=600006;
int lenn, lenm, lena, lenb, got[Lim], rev[Lim];
char s1[nS], s2[nS], sa[nS], sb[nS];
vector<int> pos;
void getkmp() {
static int p[nS];
memset(p, -1, sizeof(int)*lena);
int j=-1;
for(int i=1; i<lena; ++i) {
while(j!=-1 && sa[j+1]!=sa[i]) j=p[j];
if(sa[j+1]==sa[i]) ++j;
p[i]=j;
}
j=-1;
for(int i=0; i<lena; ++i) {
while(j!=-1 && sb[j+1]!=sa[i]) j=p[j];
if(sb[j+1]==sa[i]) ++j;
if(j==lenb-1) {
int t=i-j;
if(t%7==0) {
pos.push_back(t/7);
}
}
}
}
struct icp {
double r, i;
icp(double _r=0, double _i=0) : r(_r), i(_i) { }
};
icp operator + (const icp &a, const icp &b) { return icp(a.r+b.r, a.i+b.i); }
icp operator - (const icp &a, const icp &b) { return icp(a.r-b.r, a.i-b.i); }
icp operator * (const icp &a, const icp &b) { return icp(a.r*b.r-a.i*b.i, a.r*b.i+a.i*b.r); }
int getlen(int n) {
int len=1, bl=-1;
for(; len<n; len<<=1, ++bl);
for(int i=0; i<len; ++i) {
rev[i]=(rev[i>>1]>>1)|((i&1)<<bl);
}
return len;
}
void fft(icp *a, int n, int flag) {
for(int i=0; i<n; ++i) {
if(rev[i]<i) {
swap(a[rev[i]], a[i]);
}
}
for(int m=2; m<=n; m<<=1) {
icp wn(cos(pi*2/m), sin(pi*2/m)*flag);
for(int i=0, mid=m>>1; i<n; i+=m) {
icp w(1);
for(int j=0; j<mid; ++j) {
icp u=a[i+j], v=a[i+j+mid]*w;
a[i+j]=u+v;
a[i+j+mid]=u-v;
w=w*wn;
}
}
}
if(flag==-1) {
for(int i=0; i<n; ++i) {
a[i].r/=n;
}
}
}
void dofft(char *A, char *B, int *C, int n, int m) {
#define CLR(a) for(int i=0; i<len; ++i) a[i].r=a[i].i=0;
static icp a[Lim], b[Lim], c[Lim];
int len=getlen(n+m-1);
CLR(a);
CLR(b);
CLR(c);
for(int i=0; i<n; ++i)
a[i].r=A[i]-'0';
for(int i=0; i<m; ++i)
b[i].r=B[i]-'0';
fft(a, len, 1);
fft(b, len, 1);
for(int i=0; i<len; ++i)
c[i]=a[i]*b[i];
fft(c, len, -1);
for(int i=0; i<len; ++i)
C[i]+=c[i].r+0.5;
}
void getfft() {
lena=lenb=0;
for(int i=7; i<lenn; i+=8)
sa[lena++]=s1[i];
for(int i=lenm-1; i>=0; i-=8)
sb[lenb++]=s2[i];
dofft(sa, sb, got, lena, lenb);
for(int i=0; i<lena; ++i)
sa[i]=sa[i]=='0'?'1':'0';
for(int i=0; i<lenb; ++i)
sb[i]=sb[i]=='0'?'1':'0';
dofft(sa, sb, got, lena, lenb);
}
int main() {
int n, m;
scanf("%d%d", &n, &m);
lenn=n*8, lenm=m*8;
char *it;
it=s1;
for(int i=0; i<n; ++i) {
scanf("%s", it);
for(; *it; ++it) {
if(*(it+1)) {
sa[lena++]=*it;
}
}
}
it=s2;
for(int i=0; i<m; ++i) {
scanf("%s", it);
for(; *it; ++it) {
if(*(it+1)) {
sb[lenb++]=*it;
}
}
}
getkmp();
getfft();
if(!pos.size()) {
puts("No");
return 0;
}
int ans1=n, ans2=~0u>>1;
for(int i=0, len=pos.size(); i<len; ++i) {
int p=pos[i], t=(m-got[p+m-1]);
if(ans2==t) {
ans1=min(p, ans1);
}
else if(ans2>t) {
ans2=t;
ans1=p;
}
}
printf("Yes\n%d %d\n", ans2, ans1+1);
return 0;
}

弱省互测#2 t3的更多相关文章

  1. 弱省互测#1 t3

    题意 给出一棵n个点的树,求包含1号点的第k小的连通块权值和.(\(n<=10^5\)) 分析 k小一般考虑堆... 题解 堆中关键字为\(s(x)+min(a)\),其中\(s(x)\)表示\ ...

  2. 弱省互测#0 t3

    Case 1 题意 要求给出下面代码的答案然后构造输入. 给一个图, n 个点 m 条边 q 次询问,输出所有点对之间最大权值最小的路径. 题解 把每一个询问的输出看成一条边,建一棵最小生成树. Ca ...

  3. 【CH 弱省互测 Round #1 】OVOO(可持久化可并堆)

    Description 给定一颗 \(n\) 个点的树,带边权. 你可以选出一个包含 \(1\) 顶点的连通块,连通块的权值为连接块内这些点的边权和. 求一种选法,使得这个选法的权值是所有选法中第 \ ...

  4. 弱省互测#2 t2

    题意 给两个树,大小分别为n和m,现在两棵树各选一些点(包括1),使得这棵树以1号点为根同构(同构就是每个点的孩子数目相同),求最大的同构树.(n, m<=500) 分析 我们从两棵树中各取出一 ...

  5. 弱省互测#0 t2

    题意 给定两个字符串 A 和 B,求下面四个问题的答案: 1.在 A 的子串中,不是 B 的子串的字符串的数量. 2.在 A 的子串中,不是 B 的子序列的字符串的数量. 3.在 A 的子序列中,不是 ...

  6. 弱省互测#0 t1

    题意 给一个\(N \times M\)的01网格,1不能走,从起点\((1, 1)\)走到\((N, M)\),每次只能向下或向右走一格,问两条不相交的路径的方案数.(n, m<=1000) ...

  7. 【loj2461】【2018集训队互测Day 1】完美的队列

    #2461. 「2018 集训队互测 Day 1」完美的队列 传送门: https://loj.ac/problem/2461 题解: 直接做可能一次操作加入队列同时会弹出很多数字,无法维护:一个操作 ...

  8. 【2018集训队互测】【XSY3372】取石子

    题目来源:2018集训队互测 Round17 T2 题意: 题解: 显然我是不可能想出来的……但是觉得这题题解太神了就来搬(chao)一下……Orzpyz! 显然不会无解…… 为了方便计算石子个数,在 ...

  9. 洛谷 P4463 - [集训队互测 2012] calc(多项式)

    题面传送门 & 加强版题面传送门 竟然能独立做出 jxd 互测的题(及其加强版),震撼震撼(((故写题解以祭之 首先由于 \(a_1,a_2,\cdots,a_n\) 互不相同,故可以考虑求出 ...

随机推荐

  1. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

  2. WhatsApp的Erlang世界

    rick 的两个ppt整理 下载:2012 2013  ,使用半年erlang后,重新看这两个ppt才发现更多值的学习的地方,从ppt中整理如下: - Prefer os:timestamp to e ...

  3. 设计模式--适配器模式Adapter(结构型)

    一.适配器模式 适配器模式的主要作用是在新接口和老接口之间进行适配.将一个类的接口转换成客户端期望的另外一个接口.其实适配器模式有点无赖之举,在前期设计的时候,我们就不应该考虑适配器模式,而应该通过重 ...

  4. 461. Hamming Distance

    https://leetcode.com/problems/hamming-distance/ 将两个二进制数比较,输出不同位数的个数 Input: x = 1, y = 4 Output: 2 Ex ...

  5. linux 文件系统

    / 根目录 /bin 存放着启动时所需要的普通程序.很多程序在启动以后也很有用,它们放在这个目录下是因为它们经常要被其他程序调用 /boot 很多Linux系统把内核映像和其他一些和启动有关的文件都放 ...

  6. 网页端打开手机上的app

    iOS/Android 浏览器(h5)及微信中唤起本地APP 在移动互联网,链接是比较重要的传播媒质,但很多时候我们又希望用户能够回到APP中,这就要求APP可以通过浏览器或在微信中被方便地唤起. 这 ...

  7. python之platform模块

    python之platform模块 ^_^第三个模块从天而降喽!! 函数列表 platform.system() 获取操作系统类型,windows.linux等 platform.platform() ...

  8. 分布式之ZookeeperMac安装

    Zookeeper用于分布式计算中的协调员,观察员,观察者,分布式锁,在系统中利用Zookeeper来处理事件通知,队列,锁等功能. 使用brew安装 zookeeper. 可参考:http://bl ...

  9. ORA-12541:TNS:no listener 客户端tnsnames.ora配置,以及服务端listener.ora配置

    需求:客户端(192.168.25.1)需要访问服务端(192.168.7.215)的Oracle库ORCL. 步骤一:配置客户端tnsnames.ora 步骤二:配置服务端listener.ora ...

  10. PHP 继承多态知识点

    //1.封装//目的:为了使类更加安全//做法://1.将成员变量变为私有的//2.在类里面做一个方法来间接的访问成员变量//3.在该方法里面加控制 //2.继承//1.父类//2.子类//子类可以继 ...