[Bzoj4943][Noi2017]蚯蚓(hash)

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);
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/lzdhydzzh/p/9187864.html