dtoi3856 蚯蚓排队

题意:

     此题为NOI2017D1T2,题目链接如下

     https://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf

题解:

     本题的做法实际上比较暴力。观察数据范围,我们发现k很小,那么这意味着我们将两只蚯蚓合并的时候,只有首尾的k个字符会发生影响,那么我们只需要把新增加的贡献加上即可,删除同理,只不过变成减掉。

     那么拼接起来产生的贡献(或消除掉的贡献),实际上就是用k^2的效率暴力枚举起点和终点,然后删掉它对应的字符串的答案。这个操作我们可以使用hash表来维护,但是考虑到容易起冲突,我们改成使用trie树维护。

     询问的时候,注意一些细节处理,为了使效率高,我们还需要维护trie树上某个节点,删掉最前面一个字符之后会跳到哪个位置(方便快速查询),这样总复杂度就可以接受了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int k=50,mod=998244353;
int n,m,len,t[8][20000002];
long long ans;
char ch[10000002];
typedef struct{
    int w,las,nex;
}P;
P p[200002];
int read()
{
    int data=0,w=1; char ch=0;
    while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    if(ch=='-'){w=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){data=data*10+ch-'0';ch=getchar();}
    return data*w;
}
int main()
{
    n=read();m=read();
    for (int i=1;i<=n;i++)
    {
        p[i].w=read();p[i].las=p[i].nex=-1;
        if (!t[p[i].w][0])t[p[i].w][0]=++len;
        t[0][t[p[i].w][0]]++;
    }
    while(m--)
    {
        int u;
        u=read();
        if (u==1)
        {
            int a,b,c,root;bool u;
            a=read();b=read();
            p[a].nex=b;p[b].las=a;
            for (int i=a;i!=-1;i=p[i].las)
            {
                c=u=root=0;
                for (int j=i;c<k&&j!=-1;j=p[j].nex)
                {
                    if (!t[p[j].w][root])
                    {
                        t[p[j].w][root]=++len;
                        if (t[7][root]==-1 || !t[p[j].w][t[7][root]])
                        t[7][len]=-1;
                        else t[7][len]=t[p[j].w][t[7][root]];
                    }
                    root=t[p[j].w][root];
                    if (j==b)u=1;t[0][root]+=u;
                    c++;
                }
                if (!u)break;
            }
        }
        else if (u==2)
        {
            int a,b,c,root;bool u;
            a=read();b=p[a].nex;
            for (int i=a;i!=-1;i=p[i].las)
            {
                c=u=0;root=0;
                for (int j=i;c<k&&j!=-1;j=p[j].nex)
                {
                    root=t[p[j].w][root];
                    if (j==b)u=1;t[0][root]-=u;
                    c++;
                }
                if (!u)break;
            }
            p[a].nex=p[b].las=-1;
        }
        else
        {
            int a,l,root=0;ans=0;
            scanf("%s",ch);a=read();l=strlen(ch);
            for (int i=0;i<a;i++)
            {
                root=t[ch[i]-48][root];if (!root)goto ccj;
            }
            ans=t[0][root];
            for (int i=a;i<l;i++)
            {
                root=t[7][root];if (root<0){ans=0;goto ccj;}
                root=t[ch[i]-48][root];if (!root){ans=0;goto ccj;}
                ans=ans*t[0][root]%mod;
            }
            ccj:printf("%lld
",ans);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/1124828077ccj/p/12337901.html