题目:

Description

CJB天天要跟妹子聊天,可是他对微信的加密算法表示担心:“微信这种加密算法,早就过时了,我发明的加密算法早已风靡全球,安全性天下第一!”

CJB是这样加密的:设CJB想加密的信息有 m 个字节。首先,从网上抓来一张 n(n≥m) 个字节的图片,分析里面的每个字节(byte)。每个字节有8位(bit)二进制数字。他想替换掉某些字节中最低位的二进制数字,使得这张图片中,连续 m 个字节恰为他想加密的信息。这样,图片看起来没什么区别,却包含了意味深长的信息。

很显然,不是所有的图片都能让CJB加密他那 m 个字节的信息。他想请你帮忙写个程序判断这张图片是否能加密指定的信息。如果可以加密,则CJB要求改变最少的字节数。如果仍有多种解,他希望信息在图片中的位置越前越好。

Input

第一行包含两个整数 n,m(1≤n,m≤250000) ,表示图片的大小和信息的大小。

第二行表示图片的内容。

第三行表示信息的内容。

所有内容都以二进制字节的形式给出。每个字节有8位,最左边是最高位,最右边为最低位。

Output

如果这张图片不能加密这些信息,输出No

否则第一行输出Yes,第二行输出两个整数:最少修改的字节数,加密信息的起始位置。如果有多组解,要求加密信息的起始位置尽量前。

Sample Input

【样例输入1】
3 2
11110001 11110001 11110000
11110000 11110000
【样例输入2】
3 1
11110000 11110001 11110000
11110000

Sample Output

【样例输出1】
Yes
1 2
【样例输出2】
Yes
0 1

HINT

【样例解释】

图片有3个字节,信息有2个字节。

图片前两个字节可以匹配信息,需要改变两个字节中的最低位。

图片后两个字节可以匹配信息,只需要改变一个字节(第二个字节)中的最低位,信息在图片中的起始位置为第2个字节。

【数据范围与约定】

对于10%的数据, n,m≤500

对于40%的数据, n,m≤5000

对于70%的数据, n,m≤105

对于所有数据, 1≤n,m≤2.5×105


题解:

本题解法:KMP+FFT。

首先,先去掉最低位,跑一次KMP,记录所有可以加密为信息的起始位置。

然后我们只保留最低位,存入a, b数组里。我们很容易发现,从第 i 个字节作为起始位置计算的话,答案为

∑j=1ma[i+j] xor b[j]

我们可以把b反过来,即可变成卷积形式。

其中,异或可以拆成两个乘法操作相加,即:a xor b=(a∗!b)+(!a∗b) ,那么我们做两次FFT就可以解决了~

心得:

  又一道fft求卷积题····表示做了这么多次fft终于有点感觉了,其实以后做题要是推出了带∑的式子应该快点想到fft的··只要想办法把里面的运算变成相乘的就行了···

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cctype>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int N=;
const double pi=acos(-1.0);
int a[N],b[N],c[N],d[N];
int n,m;
int able[N],tot,rev[N];
int nxt[N],k,xj;
int ansa[N],ansb[N];
char s[N];
struct Complex {
double r,i;
Complex (double r=,double i=):r(r),i(i) {}
} A[N],C[N],B[N],D[N];
Complex operator + (Complex &a,Complex &b) {
return Complex(a.r+b.r,a.i+b.i);
}
Complex operator - (Complex &a,Complex &b) {
return Complex(a.r-b.r,a.i-b.i);
}
Complex operator * (Complex &a,Complex &b) {
return Complex(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);
}
Complex operator / (Complex &a,double x) {
return Complex(a.r/x,a.i/x);
}
inline void kmp()
{
for (int i=,j=;i<=m;++i) {
while (j && b[i]!=b[j+]) j=nxt[j];
nxt[i]=(b[i]==b[j+]?++j:j);
}
for (int i=,j=;i<=n;++i) {
while (j && a[i]!=b[j+]) j=nxt[j];
if (a[i]==b[j+]) ++j;
if (j==m) able[++tot]=i-m+,j=nxt[j];
}
}
inline void pre()
{
for (k=,xj=;k<=(n<<);k<<=,++xj);
for (int i=;i<k;++i) rev[i]=(rev[i>>]>>)|((i&)<<(xj-));
}
void fft(Complex a[],int len,int op=) {
for (int i=;i<len;++i) if (i<rev[i]) swap(a[i],a[rev[i]]);
for (int i=;i<=len;i<<=) {
Complex wn(cos(pi/i),sin(pi/i)*op);
for (int j=;j<len;j+=i) {
Complex w();
for (int k=j;k<j+i/;++k,w=w*wn) {
Complex u=a[k],v=a[k+i/]*w;
a[k]=u+v,a[k+i/]=u-v;
}
}
}
if (op==-) {
for (int i=;i<len;++i) a[i]=a[i]/len;
}
}
int main()
{
//freopen("a.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&a[i]);
for(int i=;i<=m;i++)
scanf("%d",&b[i]);
for(int i=;i<=n;i++)
c[i]=a[i]%;
for(int i=;i<+m;i++)
d[i]=b[i]%;
for(int i=;i<=n;i++)
a[i]=a[i]/;
for(int i=;i<=m;i++)
b[i]=b[i]/;
kmp();
if(!tot)
{
cout<<"No"<<endl;
return ;
}
else
cout<<"Yes"<<endl;
pre();
for (int i=;i<k;++i) A[i]=B[i]=Complex();
for (int i=;i<=n;++i) A[i]=c[i];
for (int i=;i<=m;++i) B[i]=!d[m-i+];
fft(A,k);
fft(B,k);
for (int i=;i<k;++i) A[i]=A[i]*B[i];
fft(A,k,-);
for (int i=m+;i<=n+;++i) ansa[i-m]=(int)(A[i].r+0.5); for (int i=;i<k;++i) A[i]=B[i]=Complex();
for (int i=;i<=n;++i) A[i]=!c[i];
for (int i=;i<=m;++i) B[i]=d[m-i+];
fft(A,k);
fft(B,k);
for (int i=;i<k;++i) A[i]=A[i]*B[i];
fft(A,k,-);
for (int i=m+;i<=n+;++i) ansb[i-m]=(int)(A[i].r+0.5); for(int i=;i<=n-m+;i++)
ansa[i]+=ansb[i]; int anspos,minchange=1e+;
for(int i=;i<=tot;i++)
{
if(minchange>ansa[able[i]])
{
minchange=ansa[able[i]];
anspos=able[i];
}
}
cout<<minchange<<" "<<anspos<<endl;
return ;
}
 

北京集训TEST16——图片加密(fft+kmp)的更多相关文章

  1. [2016北京集训试题15]项链-[FFT]

    Description Solution 设y[i+k]=y[i]+n. 由于我们要最优解,则假如将x[i]和y[σ[i]]连线的话,线是一定不会交叉的. 所以,$ans=\sum (x_{i}-y_ ...

  2. 【2017 北京集训 String 改编版】子串

    题意 你有一个字符串,你需要支持两种操作: 1:在字符串的末尾插入一个字符 \(c\) 2:询问当前字符串的 \([l,r]\) 子串中的不同子串个数 为了加大难度,操作会被加密(强制在线). \(n ...

  3. cocos2dx 3.x(TexturePacker进行图片加密)

    游戏开发过程中要涉及到大量的图片,使用TexturePacker可以把小图合成大图.这是我们使用最多的功能,但是TexturePacker还带有对图片加密的功能.之前还是对加密不慎了解,所以写下来分享 ...

  4. php实现图片加密解密,支持加盐

    一个简单的图片加解密函数 使用client跑,不要使用浏览器跑 qq845875470 ,技术交流 <?php /** * Created by hello. * User: qq 845875 ...

  5. c# 图片加密解密的实例代码

    c# 图片加密解密的实例代码. 代码: using System; using System.Collections.Generic; using System.Text; using System. ...

  6. 【北京集训D2T3】tvt

    [北京集训D2T3]tvt \(n,q \le 1e9\) 题目分析: 首先需要对两条路径求交,对给出的四个点的6个lca进行分类讨论.易于发现路径的交就是这六个lca里面最深的两个所形成的链. 然后 ...

  7. cocos2dx 单张图片加密

    cocos2dx 已经封装好读取加密的prv文件的方法,打开texturepacker,导入一张图片,在content protection中写入密钥,在texture format中选择prv格式 ...

  8. (2016北京集训十)【xsy1528】azelso - 概率期望dp

    北京集训的题都是好题啊~~(于是我爆0了) 注意到一个重要的性质就是期望是线性的,也就是说每一段的期望步数可以直接加起来,那么dp求出每一段的期望就行了... 设$f_i$表示从$i$出发不回到$i$ ...

  9. cocos2dx图片加密解密(npk方式)

    话不多说,直接开始: 准备的工具: 链接:https://pan.baidu.com/s/1Om4kBNWcG2jL_RTsHqqzpQ 提取码:bv7i npkCreate.exe是加密图片的工具, ...

随机推荐

  1. SQL中的动态语句执行--exec(@sqlstr)

    begin drop table #tmptable declare @money ut_money set @money=1.2345 create table #tmptable ( je ut_ ...

  2. CodeForces 149D Coloring Brackets (区间DP)

    题意: 给一个合法的括号序列,仅含()这两种.现在要为每对括号中的其中一个括号上色,有两种可选:蓝or红.要求不能有两个同颜色的括号相邻,问有多少种染色的方法? 思路: 这题的模拟成分比较多吧?两种颜 ...

  3. NBUT 1117 Kotiya's Incantation(字符输入处理)

    题意: 比较两个串,有三种情况:完全相同,可见字符相同,不同.每个字符串以'-'结尾.难点在输入. 思路: 字符逐个读入,直到'-'为止,读出两串就可以直接进行判断.如果不足两串则结束.输入时需要注意 ...

  4. Tunneling cannot be enabled without the local_ip bound to an interface on the host. Please configure local_ip 192.168.30.71 on the host interface to be used for tunneling and restart the agen

    按照官方文档配置linux bridge 会出现一下问题 Tunneling cannot be enabled without the local_ip bound to an interface ...

  5. iOS 随机数(Fixed)

    ios 有如下三种随机数方法: 1.    srand((unsigned)time(0));  //不加这句每次产生的随机数不变         int i = rand() % 5; 2.     ...

  6. 五、Pandas玩转数据

    Series的简单运算 import numpy as np import pandas as pd s1=pd.Series([1,2,3],index=['A','B','C']) print(s ...

  7. BOM函数之history对象

    前面的话 history对象保存着用户上网的历史记录,从窗口被打开的那一刻算起.由于安全方面的考虑,开发人员无法得到用户浏览器的URL,但借由用户访问过的页面列表,可以在不知道实际URL的情况下实现后 ...

  8. ThinkPHP5.0-多语言切换

    这两天做得项目中需要多语言切换,于是乎就看了看文档,感觉有些乱,就使用了终极必杀--百度. 借鉴了网上各位大佬所集成.整理出一篇比较适合类似我这种比较菜的随笔吧. 请各位大佬轻虐.感谢. 首先,不说其 ...

  9. bootstrap下拉菜单(Dropdowns)

    本章将重点讲解bootstrap下拉菜单(Dropdowns),下拉菜单是可切换的,是以列表格式显示链接的上下文菜单. <!DOCTYPE html><html><hea ...

  10. Eclipse调试:Run on server 和 Debug on server 区别

    Run on server: 以正常模式运行程序.会直接把程序从头到尾执行一遍,运行完就结束,不会进入到源代码里面(即使源代码中设置了断点). Debug on server: 以调试模式运行程序,或 ...