当前位置: 首页 > news >正文

URAL1966 Cipher Message 3

题目描述

题解:

能看出来的是,每一组数只能改最后一位,所以前$7$位动不了。

所以$KMP$跑一跑。

重点在于最后一位怎么搞。

如果$KMP$跑完了还没找到合适的位置,直接$puts("No")$就好了。

剩下个匹配问题。

(要不是数据范围拦着我我都想建图跑费用流了)

这个匹配可以用$FFT$求。

$FFT$不是求$\sum(a[i]*b[j-i])$的吗?怎么求字符串匹配?

其实我们只想要最后多项式中某一位上的值,所以$b[j-i]$和$b[i]$没有区别,反转数组就好了。

我们要求的是需要多少个$0$变成$1$,以及多少个$1$变成$0$。

所以$FFT$求两遍卷积,第一次$a[i]=[s1[i]==0],b[i]=[s2[i]==1]$,注意这里的$b$还没有反转。

第二次反过来就可以了。

代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ull;
const int N = 270050;
const ull seed = 131;
const double Pi = acos(-1.0);
template<typename T>
inline void read(T&x)
{
    T f = 1,c = 0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
    x = f*c;
}
struct cp
{
    double x,y;
    cp(){}
    cp(double x,double y):x(x),y(y){}
    cp operator + (const cp&a)const{return cp(x+a.x,y+a.y);}
    cp operator - (const cp&a)const{return cp(x-a.x,y-a.y);}
    cp operator * (const cp&a)const{return cp(x*a.x-y*a.y,x*a.y+y*a.x);}
};
int to[4*N],lim=1,l;
void fft(cp *a,int len,int k)
{
    for(int i=0;i<len;i++)
        if(i<to[i])swap(a[i],a[to[i]]);
    for(int i=1;i<len;i<<=1)
    {
        cp w0(cos(Pi/i),k*sin(Pi/i));
        for(int j=0;j<len;j+=(i<<1))
        {
            cp w(1,0);
            for(int o=0;o<i;o++,w=w*w0)
            {
                cp w1 = a[j+o],w2 = a[j+o+i]*w;
                a[j+o] = w1+w2;
                a[j+o+i] = w1-w2;
            }
        }
    }
    if(k==-1)
        for(int i=0;i<len;i++)
            a[i].x/=len;
}
void rd(int n,int *a1,int *a2)
{
    for(int x,i=1;i<=n;i++)
    {
        read(x);
        a1[i] = x%10;
        a2[i] = x/10;
    }
}
int n,m,a[2][N],b[2][N];
bool vis[N];
int ans[N];
cp c1[4*N],c2[4*N],c3[4*N];
int nxt[N];
void get_nxt(int *a,int len)
{
    int i = 1,j = 0;
    while(i<=len)
    {
        if(!j||a[i]==a[j])
        {
            i++,j++;
            nxt[i] = j;
        }else j = nxt[j];
    }
}
int kmp(int *a,int la,int *b,int lb)
{
    int ret = 0;
    int i = 1,j = 1;
    while(i<=la)
    {
        if(a[i]==b[j]||j==0)
        {
            i++,j++;
            if(j==lb+1)
            {
                vis[i-1]=1;
                j = nxt[j];
                ret = 1;
            }
        }else j=nxt[j];
    }
    return ret;
}
void work()
{
    fft(c1,lim,1),fft(c2,lim,1);
    for(int i=0;i<lim;i++)c3[i]=c1[i]*c2[i];
    fft(c3,lim,-1);
}
void init()
{
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(ans,0,sizeof(ans));
    memset(vis,0,sizeof(vis));
    lim=1,l=0;
}
int main()
{
//    freopen("tt.in","r",stdin);
    while(scanf("%d%d",&n,&m)>0)
    {
    init();
    rd(n,a[0],a[1]),rd(m,b[0],b[1]);
    get_nxt(b[1],m);
    if(!kmp(a[1],n,b[1],m))
    {
        puts("No");
        continue;
    }
    puts("Yes");
    while(lim<2*(n+m))lim<<=1,l++;
    for(int i=1;i<lim;i++)to[i]=((to[i>>1]>>1)|((i&1)<<(l-1)));
    for(int i=0;i<lim;i++)c1[i]=c2[i]=cp(0,0);
    for(int i=0;i<n;i++)c1[i].x=(a[0][i+1]==1);
    for(int i=0;i<m;i++)c2[i].x=(b[0][m-i]==0);
    work();
    for(int i=0;i<n;i++)ans[i+1]=(int)(c3[i].x+0.5);
    for(int i=0;i<lim;i++)c1[i]=c2[i]=cp(0,0);
    for(int i=0;i<n;i++)c1[i].x=(a[0][i+1]==0);
    for(int i=0;i<m;i++)c2[i].x=(b[0][m-i]==1);
    work();
    for(int i=0;i<n;i++)ans[i+1]+=(int)(c3[i].x+0.5);
    int mn = N,pos=0;
    for(int i=m;i<=n;i++)
        if(vis[i]&&ans[i]<mn)
        {
            mn = ans[i];
            pos = i-m+1;
        }
    printf("%d %d\n",mn,pos);
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/LiGuanlin1124/p/10284184.html

相关文章:

  • windows 下使用 sc 添加创建exe服务;
  • 【[NOI2018]你的名字】
  • OmniPlan 3 Pro密钥
  • AI书单
  • web通用测试点总结
  • d3生成的树状图
  • Tushare模块
  • 详解Oracle partition分区表
  • centos配置NTP服务器
  • 跟我一起学机器学习:机器学习常用流程-1
  • [Leetcode] 寻找数组的中心索引
  • nginx部署成功却没有办法访问
  • 进程管理
  • S:List
  • CLOUD常用表
  • 【Redis学习笔记】2018-06-28 redis命令源码学习1
  • 07.Android之多媒体问题
  • CSS进阶篇--用CSS开启硬件加速来提高网站性能
  • CSS相对定位
  • eclipse(luna)创建web工程
  • es6
  • npx命令介绍
  • pdf文件如何在线转换为jpg图片
  • springMvc学习笔记(2)
  • Tornado学习笔记(1)
  • Vue 动态创建 component
  • Xmanager 远程桌面 CentOS 7
  • 初探 Vue 生命周期和钩子函数
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 二维平面内的碰撞检测【一】
  • 翻译:Hystrix - How To Use
  • 观察者模式实现非直接耦合
  • 回顾 Swift 多平台移植进度 #2
  • 如何设计一个微型分布式架构?
  • 什么软件可以剪辑音乐?
  • 详解移动APP与web APP的区别
  • 运行时添加log4j2的appender
  • 阿里云ACE认证学习知识点梳理
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • $GOPATH/go.mod exists but should not goland
  • (6)设计一个TimeMap
  • (C语言)二分查找 超详细
  • (附源码)计算机毕业设计高校学生选课系统
  • (南京观海微电子)——I3C协议介绍
  • (十八)SpringBoot之发送QQ邮件
  • (十六)串口UART
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (转)VC++中ondraw在什么时候调用的
  • ***检测工具之RKHunter AIDE
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET 服务 ServiceController
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • @transactional 方法执行完再commit_当@Transactional遇到@CacheEvict,你的代码是不是有bug!...
  • [ 隧道技术 ] 反弹shell的集中常见方式(二)bash反弹shell
  • [100天算法】-目标和(day 79)