zoukankan      html  css  js  c++  java
  • 【BZOJ4943】【NOI2017】蚯蚓排队(哈希)

    【BZOJ4943】【NOI2017】蚯蚓排队(哈希)

    题面

    BZOJ
    洛谷
    UOJ

    题解

    记得去年看网络同步赛的时候是一脸懵逼的。
    昨天看到(zsy)做了,今天就看了看。。
    这不是(Hash)的傻逼题吗。。。
    呜。。。
    开链表存一下前驱后继,因为询问长度不超过(50)
    那么,总的串的个数不超过(50n),暴力(hash)一下然后拿哈希表存一下就好了。
    我开始用的map然后TLE飞了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ull unsigned long long
    #define ll long long
    #define RG register
    #define MAX 222222
    #define MOD 998244353
    const int base=233;
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    char ch[10000010];
    ull pw[MAX],has[MAX];
    int nt[MAX],lt[MAX],a[MAX],g[MAX<<1];
    int n,m;
    const int mod=7654321;
    struct Hash_Table
    {
    	int h[mod],cnt;struct Line{int len,next,w;ull s;}e[10000000];
    	void Add(int len,ull s,int w)
    	{
    		int u=s%mod;
    		for(int i=h[u];i;i=e[i].next)
    			if(e[i].len==len&&e[i].s==s)
    			{e[i].w=(e[i].w+w)%MOD;return;}
    		e[++cnt]=(Line){len,h[u],w,s};h[u]=cnt;
    	}
    	int Query(int len,ull s)
    	{
    		int u=s%mod;
    		for(int i=h[u];i;i=e[i].next)
    			if(e[i].len==len&&e[i].s==s)
    				return e[i].w;
    		return 0;
    	}
    }Hash;
    void Link(int x,int y)
    {
    	nt[x]=y;lt[y]=x;
    	ull ls=0;int tot=0;
    	for(int i=x,len=49;i&&len;i=lt[i],--len)
    	{
    		ull s=0;ls+=a[i]*pw[tot++];s=ls;int l=tot+1;
    		for(int j=y;j&&l<=50;j=nt[j],++l)s=s*base+a[j],Hash.Add(l,s,1);
    	}
    }
    void Cut(int x)
    {
    	int y=nt[x];ull ls=0;int tot=0;
    	for(int i=x,len=49;i&&len;i=lt[i],--len)
    	{
    		ull s=0;ls+=a[i]*pw[tot++];s=ls;int l=tot+1;
    		for(int j=y;j&&l<=50;j=nt[j],++l)s=s*base+a[j],Hash.Add(l,s,MOD-1);
    	}
    	nt[x]=lt[y]=0;
    }
    int Query(int len)
    {
    	int l=strlen(ch+1),ret=1;ull s=0; 
    	for(int i=1;i<len;++i)s=s*base+ch[i]-48;
    	ch[0]='0';
    	for(int i=len;i<=l;++i)
    	{
    		s=s*base+ch[i]-48;
    		s-=pw[len]*(ch[i-len]-48);
    		ret=1ll*ret*Hash.Query(len,s)%MOD;
    	}
    	return ret;
    }
    int main()
    {
    	pw[0]=1;for(int i=1;i<MAX;++i)pw[i]=pw[i-1]*base;
    	n=read();m=read();
    	for(int i=1;i<=n;++i)Hash.Add(1,a[i]=read(),1);
    	while(m--)
    	{
    		int opt=read();
    		if(opt==1)
    		{
    			int x=read(),y=read();
    			Link(x,y);
    		}
    		else if(opt==2){Cut(read());}
    		else
    		{
    			scanf("%s",ch+1);int k=read();
    			printf("%d
    ",Query(k));
    		}
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    1219 总结
    1206 冲刺三
    1130 冲刺2
    1128 主页面
    1123 冲刺3
    1121 冲刺2
    1118 冲刺1
    1117 新冲刺
    0622 软件工程总结
    0617 实验四 主存空间的分配和回收
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9260663.html
Copyright © 2011-2022 走看看