1.30

一大早发现 通配符匹配 的做法被 Hack 了,之前分析的复杂度不对,dfs 朴素的复杂度好像是 \(n|s|^{k+1}\),跑满好像是 \(10^{46}\)ms,得跑 \(10^{37}\)s,整整 \(3.168808781×10^{29}\) 年😂😂😂,但是经过若干剪枝成功把水数据草过去了,但是正解显然又快又好。

把我,Shadow,Charlie_ 的做法 Hack 了,但是
神奇的 wang54321 没有被这份卡掉因为是哈希优化 bfs,太强了%%%

正解:

image

sto UU orz


感觉我是不是也要写一个做题纪要🤔🤔🤔但是反正我 2 月 2 号就走了啊那还是写个做题纪要吧

复习一下学过的知识点也挺好的。


怎么我现在的随笔已经排到 9 页了🤣🤣🤣看来还是太颓了。


image


在洛天依的怂恿下写了两道分块入门,差点被调死。看来还是太菜。


闪存遥遥领先寄

image

image

image


今天好像是效率最低的一集啊。

上午调了一上午数列分块入门2,最终调过了但是一无所获。

学了点 AC 自动机,然后只写完了板子,连洛谷简单版二都卡了半天,菜死了。

好像没了,就学了 AC 自动机。

AC自动机模板(确认有多少个子串出现过)

LuoguP3808

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=6e6+5;
int n,m,cnt;
char s[N];
namespace AC_automaton
{
   
    queue<int> q;
    struct tree
    {
        int son[26],flag,fail;
    }trie[N];
    inline void insert(char* s)
    {
        int u=1,len=strlen(s);
        for(int i=0;i<len;++i)
        {
            int v=s[i]-'a';
            if(!trie[u].son[v]) trie[u].son[v]=++cnt;
            u=trie[u].son[v];
        }
        trie[u].flag++;
    }
    inline void get_fail()
    {
        for(int i=0;i<26;++i) 
            trie[0].son[i]=1;
        q.push(1);trie[1].fail=0;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=0;i<26;++i)
            {
                int v=trie[u].son[i];
                int fail=trie[u].fail;
                if(!v) {trie[u].son[i]=trie[fail].son[i];continue;}
                trie[v].fail=trie[fail].son[i];
                q.push(v);
            }
        }
    }
    inline int find(char* s)
    {
        int u=1,ans=0,len=strlen(s);
        for(int i=0;i<len;++i)
        {  
            int v=s[i]-'a';
            int k=trie[u].son[v];
            while(k>1 && trie[k].flag!=-1)
            {
                ans+=trie[k].flag,trie[k].flag=-1;
                k=trie[k].fail;
            }
            u=trie[u].son[v];
        }
        return ans;
    }
}
using namespace AC_automaton;
namespace IO
{
    inline void close(){std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);}
    inline void Fire(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
    inline int read(){int s = 0,w = 1;char ch = getchar();while(ch<'0'||ch>'9'){ if(ch == '-') w = -1;ch = getchar();}while(ch>='0'&&ch<='9'){ s = s*10+ch-'0';ch = getchar();}return s*w;}
    inline void write(int x){char F[200];int tmp=x>0?x:-x,cnt=0;;if(x<0)putchar('-') ;while(tmp>0){F[cnt++]=tmp%10+'0';tmp/=10;}while(cnt>0)putchar(F[--cnt]);}
}
using namespace IO;
signed main()
{
    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);
    cnt=1;
    n=read();
    for(register int i=1;i<=n;++i)
        {
            cin>>s;
            insert(s);
        }
    get_fail();
    cin>>s;
    cout<<find(s);
}

求子串在文章中出现过几次 LuoguP3796

#include<bits/stdc++.h>
using namespace std;
const int N=7e5+1;
int n,cnt,ans_cnt;
int ans[N],anss[N];
string s[205];
namespace AC_automaton
{
    class
    {
     public:
        int son[26];
        int fail,num;
    }trie[N];
    inline void insert(string s,int id)
    {
        int u=0,len=s.size();
        for(int i=0;i<len;++i)
        {
            int v=s[i]-'a';
            if(!trie[u].son[v]) trie[u].son[v]=++cnt;
            u=trie[u].son[v];
        }
        trie[u].num=id;
    }
    inline void get_fail()
    {
        queue<int> q;
        for(register int i=1;i<=N;++i)
            trie[i].fail=0;
        for(register int i=0;i<26;++i) 
            if(trie[0].son[i])
                q.push(trie[0].son[i]);
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=0;i<26;++i)
            {
                if(trie[u].son[i])
                {
                    trie[trie[u].son[i]].fail=trie[trie[u].fail].son[i];
                    q.push(trie[u].son[i]);
                }
                else 
                    trie[u].son[i]=trie[trie[u].fail].son[i];
            }
        }
    }
    inline int find(string s)
    {
        memset(ans,0,sizeof(ans));
        int u=0,res=0,len=s.size();
        for(int i=0;i<len;++i)
        {  
            int v=s[i]-'a';
            u=trie[u].son[v];
            for(int j=u;j;j=trie[j].fail) ans[trie[j].num]++;
        }
        for(int i=1;i<=n;++i)
        {
            if(res<ans[i]) 
            {
                res=ans[i];
                ans_cnt=0;
            }
            if(res==ans[i]) anss[++ans_cnt]=i;
        }
        return res;
    }
}
using namespace AC_automaton;
namespace IO
{
    inline void close(){std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);}
    inline void Fire(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
    inline int read(){int s = 0,w = 1;char ch = getchar();while(ch<'0'||ch>'9'){ if(ch == '-') w = -1;ch = getchar();}while(ch>='0'&&ch<='9'){ s = s*10+ch-'0';ch = getchar();}return s*w;}
    inline void write(int x){char F[20];int tmp=x>0?x:-x,cnt=0;;if(x<0)putchar('-') ;while(tmp>0){F[cnt++]=tmp%10+'0';tmp/=10;}while(cnt>0)putchar(F[--cnt]);}
}
using namespace IO;
signed main()
{   
    // freopen("1.in","r",stdin);
    // freopen("1.out","w",stdout);
    while((n=read())!=0)
    {
        memset(trie,0,sizeof(trie));
        cnt=ans_cnt=0;
        for(register int i=1;i<=n;++i)
            cin>>s[i],insert(s[i],i);
        cin>>s[n+1];
        get_fail();
        cout<<find(s[n+1])<<'\n';    
        for(int i=1;i<=ans_cnt;++i)
            cout<<s[anss[i]]<<'\n';
    }
}

Hack My Code!

早上那道题有双倍经验了,结果双倍经验就跟 UU 的Hack 效果一样,正向反向 dfs 搜索都是90,被卡死了。因为通配符数量为 1000。


今天洛天依居然猜到了我的密码,(其实很好猜的毕竟就是我壁纸),所以把密码换成了人名,好像机房知道能猜到人名的人不超过一个,当然就是我了😋😋😋感觉自己好小丑啊还把密码设成Ta的名字有点傻逼,但是我其实是很理智的,真的。

以后尽量少开小丑版块😓😓😓


Trump 期望 5 题,厉害

posted @ 2024-01-30 17:22  HS_xh  阅读(31)  评论(1编辑  收藏  举报
init();