bzoj4943 NOI2017 蚯蚓排队
Posted nicodafagood
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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<<"\n"; } } return 0; }
以上是关于bzoj4943 NOI2017 蚯蚓排队的主要内容,如果未能解决你的问题,请参考以下文章