LOJ 2303 「NOI2017」蚯蚓排队——链表+哈希表

题目:https://loj.ac/problem/2303

想到合并的时候可以只考虑接口附近的50个,但不太会分析复杂度,而且没有清楚地想到用哈希值对应个数。

看了题解才会……

一直想用 splay ,其实链表就可以。用 unsigned long long 就不会被卡。

不能用 map ,而是要用哈希表把字符串的哈希值映射到个数上。

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll unsigned long long
using namespace std;
int rdn()
{
  int ret=0;bool fx=1;char ch=getchar();
  while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
  while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
  return fx?ret:-ret;
}
const int mod=998244353; const ll bs=10009;
const int N=2e5+5,m2=1e6+3,M=1e7+5,K=55;

int n,m,vl[N],pr[N],nt[N],ct[M];
ll tp[M],p[K],bin[K];char s[M];//ll!!! not int
namespace H{
  int hd[m2+5],xnt,nxt[M];ll to[M];
  int get(ll x)
  {
    int h=x%m2;
    for(int i=hd[h];i;i=nxt[i])
      if(to[i]==x)return i;
    to[++xnt]=x;nxt[xnt]=hd[h];hd[h]=xnt;
    return xnt;
  }
}
void mrg(int x,int y,bool fx)
{
  if(!fx){nt[x]=y; pr[y]=x;} else{y=nt[x]; nt[x]=pr[y]=0;}
  int tot=0,cr=y;
  while(cr)
    {
      tot++; tp[tot]=(tp[tot-1]*bs+vl[cr]);
      cr=nt[cr]; if(tot==49)break;
    }
  int tt=0; cr=x;
  while(cr)
    {
      tt++; p[tt]=(p[tt-1]+vl[cr]*bin[tt-1]);
      cr=pr[cr]; if(tt==49)break;
    }
  for(int i=tt;i;i--)
    for(int j=1;j<=tot;j++)
      {
    if(i+j>50)break;
    ll h=p[i]*bin[j]+tp[j];
    int tp=H::get(h);
    if(fx)ct[tp]--;
    else ct[tp]++;
      }
}
int main()
{
  n=rdn();m=rdn();
  bin[0]=1;
  for(int i=1;i<=50;i++)
    {
      bin[i]=bin[i-1]*bs;
    }
  for(int i=1;i<=n;i++)
    {
      vl[i]=rdn();
      int k=H::get(vl[i]); ct[k]++;
    }
  for(int i=1,op,x,y;i<=m;i++)
    {
      op=rdn();
      if(op==1){ x=rdn();y=rdn();mrg(x,y,0);}
      if(op==2){ x=rdn();mrg(x,0,1);}
      if(op==3)
    {
      scanf("%s",s+1); x=rdn(); y=strlen(s+1);
      for(int j=1;j<=y;j++)
        tp[j]=(tp[j-1]*bs+(s[j]-'0'));
      int ans=1;
      for(int j=x;j<=y;j++)
        {
          ll h=tp[j]-tp[j-x]*bin[x];
          int tp=H::get(h);
          ans=(long long)ans*ct[H::get(h)]%mod;
        }
      printf("%d\n",ans);
    }
    }
  return 0;
}

 

posted on 2019-06-04 19:57  Narh  阅读(201)  评论(0编辑  收藏  举报

导航