[BZOJ4943][NOI2017]蚯蚓
阿新 • • 發佈:2018-07-02
split() getc \n i+1 efi getchar() printf class 操作
bzoj
luogu
uoj
sol
用鏈表維護蚯蚓的相對順序。
發現每次詢問的\(k\le50\),所以在每次鏈表的合並與分離時,暴力找前後\(50\)個位置,然後\(O(k^2)\)地塞進\(Hash\ Table\)或者從\(Hash\ Table\)裏面刪除。
因為分離操作最多\(10^3\)次,所以合並操作最多\(n+999\)次,復雜度顯然會是對的。
code
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; int gi(){ int x=0,w=1;char ch=getchar(); while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if (ch=='-') w=0,ch=getchar(); while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return w?x:-x; } #define ull unsigned long long const int N = 2e5+5; const int base = 20020415; const int K = 51; const int mod = 998244353; int n,m,a[N],pre[N],nxt[N],f[N];ull pw[N],g[N];char s[N*50]; struct edge{ull v;int nxt,w;}E[N*99];int head[4194304],cnt; void add(ull val,int op){ int u=val&4194303,e=head[u]; for (;e;e=E[e].nxt) if (E[e].v==val) {E[e].w+=op;return;} E[e=++cnt]=(edge){val,head[u],op};head[u]=e; } int query(ull val){ int u=val&4194303,e=head[u]; for (;e;e=E[e].nxt) if (E[e].v==val) return E[e].w; return 0; } void merge(){ int x=gi(),y=gi(),l=K,r=K-1; for (int i=x;i&&l>1;i=pre[i]) f[--l]=a[i]; for (int i=y;i&&r<K*2;i=nxt[i]) f[++r]=a[i]; for (int i=1;i<=r;++i) g[i]=g[i-1]*base+f[i]; for (int i=l;i<K;++i) for (int j=K;j<=min(r,i+49);++j) add(g[j]-g[i-1]*pw[j-i+1],1); nxt[x]=y;pre[y]=x; } void split(){ int x=gi(),y=nxt[x],l=K,r=K-1; for (int i=x;i&&l>1;i=pre[i]) f[--l]=a[i]; for (int i=y;i&&r<K*2;i=nxt[i]) f[++r]=a[i]; for (int i=1;i<=r;++i) g[i]=g[i-1]*base+f[i]; for (int i=l;i<K;++i) for (int j=K;j<=min(r,i+49);++j) add(g[j]-g[i-1]*pw[j-i+1],-1); nxt[x]=pre[y]=0; } int query(){ scanf("%s",s+1);int k=gi(),len=strlen(s+1);ull val=0; for (int i=1;i<=k;++i) val=val*base+s[i]; int res=query(val); for (int i=k+1;i<=len;++i){ val=val*base+s[i]; val-=s[i-k]*pw[k]; res=1ll*res*query(val)%mod; } return res; } int main(){ n=gi();m=gi();pw[0]=1; for (int i=1;i<N;++i) pw[i]=pw[i-1]*base; for (int i=1;i<=n;++i) add(a[i]=gi()+'0',1); while (m--){ int op=gi(); if (op==1) merge(); else if (op==2) split(); else printf("%d\n",query()); } return 0; }
[BZOJ4943][NOI2017]蚯蚓