4943: [Noi2017]蚯蚓
Time Limit: 50 Sec Memory Limit: 512 MB
Submit: 237 Solved: 110
[Submit][Status][Discuss]
Description
http://www.lydsy.com/JudgeOnline/upload/Noi2017D1.pdf
Input
Output
Sample Input
Sample Output
HINT
Source
分析:
考试时秒切的一道题,看到子串长度<=50,考虑暴力hash。bzoj内存只有四分之一差评。
AC代码:(原内存可过)
# include <iostream> # include <cstdio> # include <vector> # include <cstring> using namespace std; typedef unsigned long long llu; const int N = 5e5 + 12; const int M = 1 << 25; const int mod = 998244353; const llu bac = 19997533; int n,m,a[N],hs[M + 911],mx,q[N][3],nex[N],pre[N]; llu id[M + 911],pw[112],t[M + 911]; char str[M + 911]; vector<llu>Q[N]; int read() { int x = 0;char i = getchar(); while(!isdigit(i))i = getchar(); while(isdigit(i))x = x * 10 + i - '0',i = getchar(); return x; } int ins(llu s) { int u = s % M; while(id[u]) { if(id[u] == s)return u; u = (u + 1) & (M - 1); } id[u] = s; return u; } bool add(llu s,int x) { int u = s % M; while(id[u]) { if(id[u] == s)return hs[u] += x; u = (u + 1) & (M - 1); } return 0; } int lc[112],rc[112],lx,rx,p;llu g[112]; void solve(int x,int y,int d) { lx = rx = p = 0; for(int i = 1,u = x;i < mx && u;i++,u = pre[u])lc[++lx] = a[u]; for(int i = 1,u = y;i < mx && u;i++,u = nex[u])rc[++rx] = a[u]; for(int i = lx;i >= 1;i--)g[++p] = lc[i]; for(int i = 1;i <= rx;i++)g[++p] = rc[i]; for(int i = 1;i <= p;i++)g[i] = g[i - 1] * bac + g[i]; for(int i = 0;i < lx;i++) { int r = min(i + mx,p); for(int j = lx + 1;j <= r;j++) add(g[j] - g[i] * pw[j - i],d); } } int main() { pw[0] = 1;for(int i = 1;i <= 100;i++)pw[i] = pw[i - 1] * bac; n = read();m = read(); for(int i = 1;i <= n;i++)a[i] = read(); for(int i = 1;i <= m;i++) { q[i][0] = read(); if(q[i][0] == 1)q[i][1] = read(),q[i][2] = read(); else if(q[i][0] == 2)q[i][1] = read(); else { scanf("%s",str + 1);int len = strlen(str + 1); int k = read(); mx = max(mx,k); for(int j = 1;j <= len;j++)t[j] = t[j - 1] * bac + str[j] - '0'; for(int j = k;j <= len;j++) Q[i].push_back(ins(t[j] - t[j - k] * pw[k])); } } for(int i = 1;i <= n;i++)add(a[i],1); for(int i = 1;i <= m;i++) { int x,y; if(q[i][0] == 1) { x = q[i][1];y = q[i][2]; nex[x] = y;pre[y] = x; solve(x,y,1); } else if(q[i][0] == 2) { x = q[i][1];y = nex[x]; nex[x] = pre[y] = 0; solve(x,y,-1); } else { llu ans = 1; for(int j = 0;j < Q[i].size();j++) ans = ans * (llu)hs[Q[i][j]] % mod; printf("%d\n",(int)ans); } } }