「NOI2017」蚯蚓排队 解题报告

「NOI2017」蚯蚓排队

这题真的草

你考虑\(k\)这么小,每次合并两个串,增加的有用串的数量是\(O(k^2)\)的,暴力加入这些串,求一下这些串的Hash值,塞到Hash表里面去

这里采用类似双hash的方法,一个表进行拉表,另一个表存这个串的权值

然后就是暴力搞了

犯了个很sb的错误,我把每个蚯蚓长度都-1了,这样很容易爆Hash

不过我最开始是对每个长度的串开一个Hash数组搞,这样空间大,时间常数大,卡不过去,但不会因为长度为0的情况爆hash

最后回来的时候,一直爆Hash到自闭了...


Code:

//#pragma GCC optimize("Ofast")
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define ll long long
#define ull unsigned long long
using std::min;
const int SIZE=1<<21;
char ibuf[SIZE],*iS,*iT;
#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
//#define gc() getchar()
template <class T>
void read(T &x)
{
    int f=0;x=0;char c=gc();
    while(!isdigit(c)) f|=c=='-',c=gc();
    while(isdigit(c)) x=x*10+c-'0',c=gc();
    if(f) x=-x;
}
void reads(int *s)
{
    char c=gc();
    while(!isdigit(c)) c=gc();
    while(isdigit(c)) s[++s[0]]=c-'0',c=gc();
}
const int N=300010;
const int mod=19491001;
struct Hash
{
    int head[mod],Next[N*50],siz[N*50],cnt;
    ull idx[N*50];
    void ins(int x,ull id)
    {
        for(int i=head[x];i;i=Next[i])
            if(id==idx[i])
            {
                ++siz[i];
                return;
            }
        Next[++cnt]=head[x],head[x]=cnt;
        siz[cnt]=1;
        idx[cnt]=id;
    }
    void era(int x,ull id)
    {
        for(int i=head[x];i;i=Next[i])
            if(id==idx[i])
            {
                --siz[i];
                return;
            }
        puts("err");
    }
    int qry(int x,ull id)
    {
        for(int i=head[x];i;i=Next[i])
            if(id==idx[i])
                return siz[i];
        return 0;
    }
}Ha;
const int bas=13131;
const int bas2=131;
int n,m,pre[N],suc[N],num[N],s[N];
int saki[233];
int main()
{
    read(n),read(m);
    for(int i=1;i<=n;i++)
    {
        ull idx;
        read(num[i]);
        idx=num[i];
        Ha.ins(num[i],idx);
    }
    for(int op,u,v,k,i=1;i<=m;i++)
    {
        read(op);
        if(op==1)
        {
            read(u),read(v);
            suc[u]=v,pre[v]=u;
            int now=u,l=51,r=50;
            while(now&&l)
            {
                saki[--l]=num[now];
                now=pre[now];
            }
            now=v;
            while(now&&r<=100)
            {
                saki[++r]=num[now];
                now=suc[now];
            }
            for(int i=l;i<=50;i++)
            {
                ull idx=0;
                int x=0;
                for(int j=i;j<=i+49&&j<=r;j++)
                {
                    x=(1ll*x*bas+saki[j])%mod;
                    idx=idx*bas2+saki[j];
                    if(j>50) Ha.ins(x,idx);
                }
            }
        }
        else if(op==2)
        {
            read(u),v=suc[u];
            int now=u,l=51,r=50;
            while(now&&l)
            {
                saki[--l]=num[now];
                now=pre[now];
            }
            now=v;
            while(now&&r<=100)
            {
                saki[++r]=num[now];
                now=suc[now];
            }
            for(int i=l;i<=50;i++)
            {
                ull idx=0;
                int x=0;
                for(int j=i;j<=i+49&&j<=r;j++)
                {
                    x=(1ll*x*bas+saki[j])%mod;
                    idx=idx*bas2+saki[j];
                    if(j>50) Ha.era(x,idx);
                }
            }
            suc[u]=pre[v]=0;
        }
        else
        {
            int ans=1;
            s[0]=0;
            reads(s),read(k);
            int po=1,x=0;ull ba=1,idx=0;
            for(int i=1;i<k;i++) po=1ll*po*bas%mod,ba=ba*bas2;
            for(int i=1;i<k;i++) idx=idx*bas2+s[i],x=(1ll*x*bas+s[i])%mod;
            for(int i=k;i<=s[0];i++)
            {
                idx=idx*bas2+s[i],x=(1ll*x*bas+s[i])%mod;
                ans=1ll*ans*Ha.qry(x,idx)%998244353;
                if(!ans) break;
                idx-=s[i-k+1]*ba;
                x-=1ll*s[i-k+1]*po%mod;
                if(x<0) x+=mod;
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}


2019.6.1

posted @ 2019-06-01 11:50  露迭月  阅读(276)  评论(0编辑  收藏  举报