题意

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

分析

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

题解

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

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const double pi=acos(-1);
  4. const int N=2.5e5+10, nS=N*8, Lim=600006;
  5. int lenn, lenm, lena, lenb, got[Lim], rev[Lim];
  6. char s1[nS], s2[nS], sa[nS], sb[nS];
  7. vector<int> pos;
  8. void getkmp() {
  9. static int p[nS];
  10. memset(p, -1, sizeof(int)*lena);
  11. int j=-1;
  12. for(int i=1; i<lena; ++i) {
  13. while(j!=-1 && sa[j+1]!=sa[i]) j=p[j];
  14. if(sa[j+1]==sa[i]) ++j;
  15. p[i]=j;
  16. }
  17. j=-1;
  18. for(int i=0; i<lena; ++i) {
  19. while(j!=-1 && sb[j+1]!=sa[i]) j=p[j];
  20. if(sb[j+1]==sa[i]) ++j;
  21. if(j==lenb-1) {
  22. int t=i-j;
  23. if(t%7==0) {
  24. pos.push_back(t/7);
  25. }
  26. }
  27. }
  28. }
  29. struct icp {
  30. double r, i;
  31. icp(double _r=0, double _i=0) : r(_r), i(_i) { }
  32. };
  33. icp operator + (const icp &a, const icp &b) { return icp(a.r+b.r, a.i+b.i); }
  34. icp operator - (const icp &a, const icp &b) { return icp(a.r-b.r, a.i-b.i); }
  35. 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); }
  36. int getlen(int n) {
  37. int len=1, bl=-1;
  38. for(; len<n; len<<=1, ++bl);
  39. for(int i=0; i<len; ++i) {
  40. rev[i]=(rev[i>>1]>>1)|((i&1)<<bl);
  41. }
  42. return len;
  43. }
  44. void fft(icp *a, int n, int flag) {
  45. for(int i=0; i<n; ++i) {
  46. if(rev[i]<i) {
  47. swap(a[rev[i]], a[i]);
  48. }
  49. }
  50. for(int m=2; m<=n; m<<=1) {
  51. icp wn(cos(pi*2/m), sin(pi*2/m)*flag);
  52. for(int i=0, mid=m>>1; i<n; i+=m) {
  53. icp w(1);
  54. for(int j=0; j<mid; ++j) {
  55. icp u=a[i+j], v=a[i+j+mid]*w;
  56. a[i+j]=u+v;
  57. a[i+j+mid]=u-v;
  58. w=w*wn;
  59. }
  60. }
  61. }
  62. if(flag==-1) {
  63. for(int i=0; i<n; ++i) {
  64. a[i].r/=n;
  65. }
  66. }
  67. }
  68. void dofft(char *A, char *B, int *C, int n, int m) {
  69. #define CLR(a) for(int i=0; i<len; ++i) a[i].r=a[i].i=0;
  70. static icp a[Lim], b[Lim], c[Lim];
  71. int len=getlen(n+m-1);
  72. CLR(a);
  73. CLR(b);
  74. CLR(c);
  75. for(int i=0; i<n; ++i)
  76. a[i].r=A[i]-'0';
  77. for(int i=0; i<m; ++i)
  78. b[i].r=B[i]-'0';
  79. fft(a, len, 1);
  80. fft(b, len, 1);
  81. for(int i=0; i<len; ++i)
  82. c[i]=a[i]*b[i];
  83. fft(c, len, -1);
  84. for(int i=0; i<len; ++i)
  85. C[i]+=c[i].r+0.5;
  86. }
  87. void getfft() {
  88. lena=lenb=0;
  89. for(int i=7; i<lenn; i+=8)
  90. sa[lena++]=s1[i];
  91. for(int i=lenm-1; i>=0; i-=8)
  92. sb[lenb++]=s2[i];
  93. dofft(sa, sb, got, lena, lenb);
  94. for(int i=0; i<lena; ++i)
  95. sa[i]=sa[i]=='0'?'1':'0';
  96. for(int i=0; i<lenb; ++i)
  97. sb[i]=sb[i]=='0'?'1':'0';
  98. dofft(sa, sb, got, lena, lenb);
  99. }
  100. int main() {
  101. int n, m;
  102. scanf("%d%d", &n, &m);
  103. lenn=n*8, lenm=m*8;
  104. char *it;
  105. it=s1;
  106. for(int i=0; i<n; ++i) {
  107. scanf("%s", it);
  108. for(; *it; ++it) {
  109. if(*(it+1)) {
  110. sa[lena++]=*it;
  111. }
  112. }
  113. }
  114. it=s2;
  115. for(int i=0; i<m; ++i) {
  116. scanf("%s", it);
  117. for(; *it; ++it) {
  118. if(*(it+1)) {
  119. sb[lenb++]=*it;
  120. }
  121. }
  122. }
  123. getkmp();
  124. getfft();
  125. if(!pos.size()) {
  126. puts("No");
  127. return 0;
  128. }
  129. int ans1=n, ans2=~0u>>1;
  130. for(int i=0, len=pos.size(); i<len; ++i) {
  131. int p=pos[i], t=(m-got[p+m-1]);
  132. if(ans2==t) {
  133. ans1=min(p, ans1);
  134. }
  135. else if(ans2>t) {
  136. ans2=t;
  137. ans1=p;
  138. }
  139. }
  140. printf("Yes\n%d %d\n", ans2, ans1+1);
  141. return 0;
  142. }

弱省互测#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. springMVC的配置文件路径问题

    ① <init-param> <param-name>contextConfigLocation</param-name> <param-value>c ...

  2. py

    import httplib,urllib import re import random def Login(userid,password): params=urllib.urlencode({' ...

  3. Fiddler学习笔记

    1. [HTTP]Fiddler(一) - Fiddler简介 Fiddler使用代理(127.0.0.1:8888), 打开Fiddler会自动设置该代理. 2.[HTTP]Fiddler(二) - ...

  4. DevExpress GridControl 选择整行被选单元格不变色的设置

    设置GridControl 里面的 gridview 属性, 找到OptionSelection 将EnableAppearanceFocusedCell 属性设置False 就可以了 此方式同样适用 ...

  5. mysqldump和xtrabackup备份原理实现说明

    背景: MySQL数据库备份分为逻辑备份和物理备份两大类,犹豫到底用那种备份方式的时候先了解下它们的差异: 逻辑备份的特点是:直接生成SQL语句,在恢复的时候执行备份的SQL语句实现数据库数据的重现. ...

  6. ztree-demo 2

    <!DOCTYPE html> <HTML> <HEAD> <TITLE> ZTREE DEMO - Async</TITLE> <m ...

  7. [Sass]扩展/继承

    [Sass]扩展/继承 继承对于了解 CSS 的同学来说一点都不陌生,先来看一张图: 图中代码显示".col-sub .block li,.col-extra .block li" ...

  8. 【原创】web端高德地图javascript API的调用

    关于第三放地图的使用,腾讯.百度.高德 具体怎么选择看你自己怎么选择了. 高德地图开放平台:http://lbs.amap.com/ 本次使用的是高德的javascript API http://lb ...

  9. 修改linux的系统时间和时区

    时间: date命令将日期设置为2016年12月16日 ----   date -s 12/16/16 将时间设置为9点28分50秒 ----   date -s 09:28:50 时区: tzsel ...

  10. xcode添加快捷代码块

    添加快捷代码块 在开发过程中,一些常用的代码段,我们可以设置成快捷代码段来快速实现代码的编写. 如上图中的属性的设置,它们都有相同重复的代码@property (nonatomic, strong), ...