首页 > 其他分享 >Luogu P2292 HNOI2004 L 语言 题解 [ 紫 ] [ AC 自动机 ] [ 状压 dp ]

Luogu P2292 HNOI2004 L 语言 题解 [ 紫 ] [ AC 自动机 ] [ 状压 dp ]

时间:2025-01-08 21:11:56浏览次数:1  
标签:insert AC ch int 题解 状压 Luogu 1005 dp

L 语言:很好的一道状压 dp 题。

思路

看到这题,首先可以想到一个很暴力的 dp,设 \(dp_i\) 表示考虑到第 \(i\) 位能否被理解,暴力匹配字符串转移即可。

第一个优化也很显然,暴力匹配字符串换成 AC 自动机即可。

但是时间复杂度变成了 \(O(m|T||S|)\) 的,显然会被卡。

状压与位运算优化

观察到 \(|S|=20\),所以我们最多只能往前转移 \(20\) 位,这就启发我们用一个 int 存下 dp 状态,用位运算优化转移。这个技巧通常用于可行性 dp 也就是只有 \(0/1\) 状态的 dp 里。

同时我们也需要在 fail 树上预处理出某个节点能接受转移的长度,然后每次和当前 dp 状态与运算一下就好了。

时间复杂度 \(O(m|T|)\)。

坑点

dp 状态取模的时候要取 \(2_i\),如果任取一个数那么会导致 dp 完全乱掉。反例也很好举,例如 \(114514 \bmod 2^{10} \ne 114514 \bmod 1000\)。

同时字典树 insert 要用 insert(s) 而不是 insert(s+1),我已经错了两遍以上了。

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
const int mod=2097152;
int n,m,ch[1005][30],idx=0,tot[1005],ne[1005],dp=0,ans=0;
vector<int>g[1005];
char s[1005],t[4000005];
void insert(char *s)
{
    int p=0;

    for(int i=1;s[i];i++)
    {
        int c=s[i]-'a';
        if(ch[p][c]==0)ch[p][c]=++idx;
        p=ch[p][c];
    }
    tot[p]=(tot[p]|(1<<(strlen(s+1))));
}
void build()
{
    queue<int>q;
    for(int i=0;i<26;i++)
    {
        if(ch[0][i])q.push(ch[0][i]);
    }
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=0;i<26;i++)
        {
            int v=ch[u][i];
            if(v)ne[v]=ch[ne[u]][i],q.push(v);
            else ch[u][i]=ch[ne[u]][i];
        }
    }
}
void dfs1(int u)
{
    for(auto v:g[u])
    {
        tot[v]=(tot[v]|tot[u]);
        dfs1(v);
    }
}
void init()
{
    for(int i=1;i<=idx;i++)g[ne[i]].push_back(i);
    dfs1(0);
}
void solve()
{
    cin>>t+1;
    int len=strlen(t+1),p=0;
    dp=1;
    ans=0;
    for(int i=1;i<=len;i++)
    {
        int c=t[i]-'a';
        p=ch[p][c];
        int now=tot[p];
        dp<<=1;
        dp%=mod;
        int hv=(dp&now);
        if(hv)dp|=1,ans=i;
        if(dp==0)break;
    }
    cout<<ans<<'\n';
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>s+1;
        insert(s);
    }
    build();
    init();
    while(m--)solve();
    return 0;
}

标签:insert,AC,ch,int,题解,状压,Luogu,1005,dp
From: https://www.cnblogs.com/zhr0102/p/18660581

相关文章

  • 【GUI-pyqt5】QAbstractButton类
    1.描述所有按钮控件的基类提供按钮的通用功能2.继承QWidget3.功能3.1提示文本3.1.1APIAPI功能备注setText(str)设置按钮提示文本-text()获取按钮提示文本-3.1.2应用场......
  • 洛谷 P2754 [CTSC1999] 家园 / 星际转移问题——题解
    #ifdefONLINE_JUDGE#else#defineQiu_Cheng#endif#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;//typedeflonglongll;constintN=2e6+5,mod=1e9+7,inf=INT_MAX;//constintmod1=469762049,mod2=998244353,mod3=1004535......
  • P7603 [THUPC2021] 鬼街 题解
    P7603[THUPC2021]鬼街题解第一次见折半报警器的trick,记录一下首先观察到\(x\len\le10^5\),所以\(x\)最多有6个质因数,\(x=30030\)可以取到,这使得对于修改,我们可以暴力单点修改。接下来考虑询问,朴素的做法是:每一次灵异事件之后,都对所有监控器进行检验是否满足和......
  • laplacian算子
    拉普拉斯算子(LaplacianOperator)是图像处理中的一种二阶导数算子,用于检测图像中的边缘。它可以增强图像中灰度变化较大的区域,从而突出边缘特征。数学定义拉普拉斯算子在二维情况下定义为:[\Deltaf(x,y)=\frac{\partial^2f}{\partialx^2}+\frac{\partial^2f}{\partial......
  • Oracle 按工作日计算工单超期日期(跳过法定节假日)
    一、创建辅助表:用于存储法定节假日调休日点击查看代码createtableTEMP_JJRTXR(rqDATEnotnull,lxNUMBERnotnull,ztNUMBERnotnull)tablespaceUSR_xxx_TBSpctfree10initrans1maxtrans255;--Addcommentstothetablecommentontable......
  • MacOS15+Xcode版本16+对ReactNative项目进行编译和上传到APPStore的踩坑记录
    作者:Kovli重要通知:红宝书第5版2024年12月1日出炉了,感兴趣的可以去看看,https://u.jd.com/saQw1vP红宝书第五版中文版红宝书第五版英文原版pdf下载(访问密码:9696)1、编译报错如下项目名/ios/Pods/FlipperKit/iOS/FlipperKit/FlipperPlatformWebSocket.mm:57:46Calledobjec......
  • 【Spring】Redis缓存+ehcache
    文章目录基于Spring的Redis+ehcacheRedis缓存配置@Cacheable注解@CacheEvict注解缓存配置基于Spring的Redis+ehcacheRedis缓存配置在项目中添加Redis的依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-sta......
  • macOS删除程序,快准狠且不留痕,看这里!
    作为一名自由的互联网从业人员,俊伟平时经常下载各种软件来辅助他的工作。随着时间的推移,他的苹果电脑(MacBookPro)上积累了大量的软件,有些软件只用了一次就再也没动过,而有些旧软件的更新版本早已安装,但旧版本的残留文件依然留在系统中。“我的Mac运行越来越慢了,是不是该删除一......
  • mac m1 安装ffmpeg,配置环境变量
    1首先要安装brew2  gitclonehttps://git.ffmpeg.org/ffmpeg.gitffmpeg3 cdffmpeg4执行脚本 ./configure--prefix=/opt/local5编译 sudomake,需要提权,要不系统目录无法创建文件夹6安装 makeinstall7安装成功,查看 ffmpeg版本  /opt/local/bin/ffmpeg-ve......
  • Veeam Backup & Replication 11备份windows服务器,物理机迁移
    原文转自VeeamBackup&Replication11备份windows服务器,物理机迁移VeeamBackup&Replication11备份windows服务器今天用Veeam给windows服务器做备份。如果是物理机迁移至虚拟机,也可以先备份,再恢复到指导位置。 安装veeambackup&replicationconsole先在server......