zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    ACM学习历程——POJ3321 Apple Tree(搜索,线段树)
    ACM学习历程——NOJ1113 Game I(贪心 || 线段树)
    ACM学习历程——HDU5202 Rikka with string(dfs,回文字符串)
    ACM学习历程——hihoCoder挑战赛10A 01串(策略)
    ACM学习历程——POJ3468 A Simple Problem with Integers(线段树)
    ACM学习历程——POJ1260 Pearls(动态规划)
    java入门了解09
    java入门了解08
    java入门了解之快捷键
    java入门了解07
  • 原文地址:https://www.cnblogs.com/1124828077ccj/p/12337901.html
Copyright © 2011-2022 走看看