Increase the Constraints

定义两个等长的01字符串的汉明距离为它们字符不同的对应位置的个数。

给你两个01串S,T,现在有q个询问,每次指定S,T中两个定长的子串询问它们的汉明距离。

1≤|S|,|T|≤200000,1≤q≤400000

cz_xuyixuan的题解

字符不同=长度-字符相同。考虑到两个字符串的匹配问题可以用FFT处理,于是往FFT方面考虑。

分块FFT,令分块大小为B,进行O(\(\frac{n}{B}\))次FFT,处理出O(\(\frac{n}{B}\))个T的后缀与S的每个后缀能够匹配的位数。询问时容斥一下并加上边角暴力就好了。

这样的时间复杂度是O(\(\frac{n^2\log n}{B}\)+qB),取B=n\(\sqrt{\frac{\log n}{q}}\)=‭1,327.013205时,可以获得渐进意义下最优复杂度O(n\(\sqrt{q log n}\))。

有一种高妙的做法来解决01匹配问题。我们令0为1,1为-1,然后FFT。那么两个字符如果匹配,得数为1,否则为-1。我们给1和-1的总和加上长度,那么就变成了匹配得2,不匹配得0.

由于NTT常数大,所以程序取B=7200。

CO int N=524288;
int rev[N],omg[N]; void NTT(int a[],int lim,int dir){
for(int i=0;i<lim;++i)
if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int i=1;i<lim;i<<=1)
for(int j=0;j<lim;j+=i<<1)
for(int k=0;k<i;++k){
int t=mul(omg[lim/(i<<1)*k],a[j+i+k]);
a[j+i+k]=add(a[j+k],mod-t),a[j+k]=add(a[j+k],t);
}
if(dir==-1){
int ilim=fpow(lim,mod-2);
for(int i=0;i<lim;++i) a[i]=mul(a[i],ilim);
}
} CO int B=7200;
char s[N],t[N];int ls,lt;
int index[N],l[N],r[N],tot;
int a[N],b[N],ans[N/B][N]; int query(int ps,int pt){
int ans=0;
if(ps+B>=ls or pt+B>=lt){
for(;ps<ls and pt<lt;++ps,++pt) ans+=s[ps]==t[pt];
return ans;
}
for(;index[pt]==index[pt-1];++ps,++pt) ans+=s[ps]==t[pt];
ans+=::ans[index[pt]][ps];
return ans;
}
int main(){
scanf("%s%s",s,t);
ls=strlen(s),lt=strlen(t);
for(int i=0;i<lt;++i){
if(i%B==0) l[++tot]=i;
index[i]=tot,r[tot]=i;
}
for(int p=1;p<=tot;++p){
memset(a,0,sizeof a);
for(int i=0;i<ls;++i) a[i]=s[i]=='0'?1:mod-1;
memset(b,0,sizeof b);
for(int i=l[p];i<lt;++i) b[lt-1-i]=t[i]=='0'?1:mod-1;
int n=lt-l[p]-1; int len=ceil(log2(ls+n)),lim=1<<len;
for(int i=0;i<lim;++i) rev[i]=rev[i>>1]>>1|(i&1)<<(len-1);
omg[0]=1,omg[1]=fpow(3,(mod-1)/lim);
for(int i=2;i<lim;++i) omg[i]=mul(omg[i-1],omg[1]);
NTT(a,lim,1),NTT(b,lim,1);
for(int i=0;i<lim;++i) a[i]=mul(a[i],b[i]);
omg[1]=fpow(omg[1],mod-2);
for(int i=2;i<lim;++i) omg[i]=mul(omg[i-1],omg[1]);
NTT(a,lim,-1); for(int i=0;i<ls;++i){
ans[p][i]=add(a[i+n],add(n+1,mod-max(0,i+n-ls+1))); // edit 1
ans[p][i]=mul(ans[p][i],i2);
}
}
for(int q=read<int>();q--;){
int ps=read<int>(),pt=read<int>(),n=read<int>();
printf("%d\n",n-query(ps,pt)+query(ps+n,pt+n));
}
return 0;
}

处理ans数组的时候还是要放到模意义下,因为1和-1的总和可能为负数。

CF472G Increase the Constraints的更多相关文章

  1. 【CF472G】Design Tutorial: Increase the Constraints

    Description 给出两个01序列\(A\)和\(B\) 要求回答\(q\)个询问每次询问\(A\)和\(B\)中两个长度为\(len\)的子串的哈明距离 ​ 哈明距离的值即有多少个位置不相等 ...

  2. cf 472G Design Tutorial: Increase the Constraints 分块+压位/FFT

    题目大意 给出两个\(01\)序列\(A\)和\(B\) 哈明距离定义为两个长度相同的序列中,有多少个对应位置上的数字不一样 "00111" 和 "10101" ...

  3. CF数据结构练习

    1. CF 438D The Child and Sequence 大意: n元素序列, m个操作: 1,询问区间和. 2,区间对m取模. 3,单点修改 维护最大值, 取模时暴力对所有>m的数取 ...

  4. Propagation of Visual Entity Properties Under Bandwidth Constraints

    1. Introduction The Saga of Ryzom is a persistent massively-multiplayer online game (MMORPG) release ...

  5. iOS Programming Auto Layout: Programmatic Constraints 自动布局:通过编程限制

    iOS Programming  Auto Layout: Programmatic Constraints  1.  However, if your views are created in co ...

  6. States of Integrity Constraints

    States of Integrity Constraints As part of constraint definition, you can specify how and when Oracl ...

  7. Go build constraints

    Go语言有一个不(奇)错(葩)的设计,就是build constraints(构建约束).可以在源码中通过注释的方式指定编译选项,比如只允许在linux下,或者在386的平台上编译啊之类的:还可以通过 ...

  8. Unable to simultaneously satisfy constraints.

    在进行版本的迭代更新时,新功能需求需要对主页面的UI进行重新的布局,但是,报了错误,出了好多约束方面的问题: Unable to simultaneously satisfy constraints. ...

  9. Drop all the tables, stored procedures, triggers, constraints and all the dependencies in one SQL statement

    Is there any way in which I can clean a database in SQl Server 2005 by dropping all the tables and d ...

随机推荐

  1. @AspectJ注解的value属性

    @Component @Scope("prototype") @Aspect(value="perthis(execution(* com.helius.service. ...

  2. docker compose 编排

    Compose是Docker的服务编排工具,主要用来构建基于Docker的复杂应用,Compose 通过一个配置文件来管理多个Docker容器,非常适合组合使用多个容器进行开发的场景. 说明:Comp ...

  3. 【C++】一个指针占几个字节?为什么呢?

    一个指针在32位操作系统上,占4个字节 一个指针在64位操作系统上,占8个字节 但是,编译器为了兼容32位操作系统和64位操作系统,所以指针都是4个字节长度 为什么呢? 在计算机中,CPU不能直接与硬 ...

  4. Functional-Light-JS 摘录笔记(1)

    function foo(...args) { console.log( args[3] ); } var arr = [ 1, 2, 3, 4, 5 ]; foo( ...arr ); Think ...

  5. Akka-CQRS(7)- CQRS Reader Actor 示范

    我们在这篇通过一个具体CQRS-Reader-Actor的例子来示范akka-persistence的query端编程和应用.在前面的博客里我们设计了一个CQRS模式POS机程序的操作动作录入过程,并 ...

  6. Java学习:JDBC快速入门

    本节类容 JDBC基本概念 快速入门 JDBC基本概念 概念: Java DataBase Connectivity Java 数据库连接,Java语言操作数据库 JDBC本质: 其实是官方(sun公 ...

  7. 大数据技术 - 为什么是SQL

    在大数据处理以及分析中 SQL 的普及率非常高,几乎是每一个大数据工程师必须掌握的语言,甚至非数据处理岗位的人也在学习使用 SQL.今天这篇文章就聊聊 SQL 在数据分析中作用以及掌握 SQL 的必要 ...

  8. Django-xadmin的使用介绍

    Django-xadmin的介绍 Django是python的重量级web框架,写得少,做得多,非常适合后端开发,它很大的一个亮点是,自带后台管理模块,但它自带的后台管理有点丑,而Xadmin是基于b ...

  9. 【JVM学习笔记二】垃圾收集器与内存分配策略

    1. 概述 1) GC的历史比Java久远 2) GC需要完成的三件事: | 哪些内存需要回收 | 什么时候回收 | 如何回收 3) Java内存运行时区域各个部分: | Java虚拟机栈.计数器.本 ...

  10. 【转载】 C#中常见的泛型集合类有哪些

    在C#语言编程过程中,List集合类是最常见的泛型集合类,其实除了List集合,还有其他一些常用的泛型集合类,如字典类型Dictionary泛型集合类.先进先出的队列类型Queue泛型集合类.后进先出 ...