• bzoj4943 NOI2017 蚯蚓排队


    给出 n 个字符,初始每个字符单独成字符串。支持 m 次操作,每次为一下三种之一:

    • 1 i j:将以 i 结尾的串和以 j 开头的串连到一起。
    • 2 i :将 i 所在串从 i 位置和 i 下一个位置之间断开。
    • 3 S k :对于字符串 S 每个长度为 k 的子串,统计它在这 n 个字符组成所有字符串中出现的次数,求所有统计结果的乘积模 998244353 的结果。

    n<=2e5 

    m<=3e5

    2操作次数小于1e3

    Σ|s|<1e7

    k<=50

    因为k<=50,所以一看就知道可以暴力维护每一个子串的hash值

    乍一看好像是nk^2的复杂度

    实际上只有合并的两个串长度都大于k才会计算k^2次

    所以大概就是nk的复杂度

    由于nk达到了1e7

    所以这里不能用map

    可以使用挂链版本的hash表

    其实代码不是很难写

    但是由于我x和y分不清楚WA了两发

    //%std
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<set>
    #include<map>
    using namespace std;
    #define lovelive long long
    #define lc son[x][0]
    #define rc son[x][1]
    #define lowbit(x) (x&(-x))
    #define pt vc
    const lovelive mod=10233333;
    const int N=2e5+100;
    const unsigned lovelive base=131;
    int head[mod+100],next[mod*2],tot;
    lovelive sum[mod*2];
    unsigned lovelive a[mod*2];
    void add(unsigned lovelive x,int k)
    {
      int j=head[x%mod];
      if(!j)
      {
          head[x%mod]=++tot;
          a[tot]=x;
          sum[tot]=k;
          return;
      }
      for(;j;j=next[j])
      {
          if(a[j]==x)
          {
            sum[j]+=k;
            break;
        }
        if(!next[j])
        {
          next[j]=++tot;
          a[tot]=x;
        }
      }
    }
    lovelive query(unsigned lovelive x)
    {
      for(int j=head[x%mod];j;j=next[j])
        if(a[j]==x)
          return sum[j];
      return 0;
    }
    int pre[N],nxt[N],d[N];
    void merge(int i,int j,int k)
    {
      unsigned lovelive hash;
      int len;
      for(int x=i;x;x=pre[x])
      {
          len=0;hash=0;
          for(int y=x;y!=j&&y;y=nxt[y])
          {
            ++len;
            hash=hash*base+d[y];
        }
        if(len>=50)
          break;
        for(int y=j;len<50&&y;len++,y=nxt[y])
        {
          hash=hash*base+d[y];
          add(hash,k);
        }
      }
      if(k==-1)
          pre[j]=nxt[i]=0;
      else
      {
          pre[j]=i;
          nxt[i]=j;
      }
    }
    void read(int &x)
    {
      int p=1;
      x=0;
      char c=getchar();
      while(c<'0'||c>'9')
      {
        if(c=='-')
          p=-1;
        c=getchar();
      }
      while(c>='0'&&c<='9')
      {
          x=x*10+c-48;
          c=getchar();
      }
      x*=p;
    }
    char s[10000010];
    unsigned lovelive hsh[10000010],pw[100];
    int main()
    {
      int n,m,k,opt,x,y,len;
      lovelive ans;
      read(n);read(m);
      for(int i=1;i<=n;i++)
        read(d[i]),add(d[i],1);
      pw[0]=1;
      for(int i=1;i<=50;i++)
        pw[i]=pw[i-1]*base;
      for(int i=1;i<=m;i++)
      {
          read(opt);
          if(opt==1)
          {
            read(x);read(y);
            merge(x,y,1);
        }
        if(opt==2)
        {
          read(x);
          merge(x,nxt[x],-1);
        }
        if(opt==3)
        {
          ans=1;
          scanf("%s",s+1);
          len=strlen(s+1);
          read(k);
          for(int j=1;j<=len;j++)
            hsh[j]=hsh[j-1]*base+s[j]-'0';
          for(int j=0;j<=len-k;j++)
          {
              ans*=query(hsh[j+k]-hsh[j]*pw[k]);
              ans%=998244353;
          }
          cout<<ans<<"
    ";
        }
      }
      return 0;
    }
    View Code
  • 相关阅读:
    XAF 有条件的对象访问权限
    XAF 顯示 UnInplace Report(設置自定義條件顯示報表,不是根據選擇ListView記錄條件顯示報表)
    XAF 如何自定义PivotGrid单元格显示文本?
    XAF 如何布局详细视图上的按钮
    XAF How to set size of a popup detail view
    XAF Delta Replication Module for Devexpress eXpressApp Framework
    XAF 帮助文档翻译 EasyTest Basics(基础)
    XAF 用户双击ListView记录时禁止显示DetailView
    XAF How to enable LayoutView mode in the GridControl in List Views
    XAF 如何实现ListView单元格批量更改?
  • 原文地址:https://www.cnblogs.com/NicoDafaGood/p/8856704.html
Copyright © 2020-2023  润新知