Live2D

Solution -「NOI 2017」「洛谷 P3823」蚯蚓排队

\(\mathscr{Description}\)

  Link.

  (自己看题, 我总不能让题意比题解还长吧?)

\(\mathscr{Solution}\)

  下一组我一定写成 solution set, 这种题就不用占题解空间了.

  维护 hash. 复杂度 \(\mathcal O(mk^2)\).

\(\mathscr{Code}\)

/* Clearink */

#include <cstdio>
#include <cassert>
#include <cstring>
#include <unordered_map>

#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )

typedef unsigned long long ULL;

inline int rint() {
    int x = 0, s = getchar();
    for ( ; s < '0' || '9' < s; s = getchar() );
    for ( ; '0' <= s && s <= '9'; s = getchar() ) x = x * 10 + ( s ^ '0' );
    return x;
}

inline void wint( const int x ) {
    if ( 9 < x ) wint( x / 10 );
    putchar( x % 10 ^ '0' );
}

const int MAXN = 2e5, MAXM = 3e5, MAXL = 1e7, MAXK = 50, MOD = 998244353;
int n, m, a[MAXN + 5];
const ULL BASE = 20050913;
ULL pwr[55];
int pre[MAXN + 5], nex[MAXN + 5];
char str[MAXL + 5];

struct HashTable {
    static const int M = 100019, MAXND = 4e5;
    int node, head[M], val[MAXND], nxt[MAXND];
    ULL key[MAXND];

    inline int& operator [] ( const ULL k ) {
        int r = head[k % M], las = -1;
        for ( ; r && key[r] != k; r = nxt[las = r] );
        if ( r ) return val[r];
        if ( !~las ) head[k % M] = r = ++node;
        else nxt[las] = r = ++node;
        return key[r] = k, val[r] = 0;
    }
} buc[51];

inline int mul( const long long a, const int b ) { return int( a * b % MOD ); }

inline void contr( const int p, const int q, const int v ) {
    ULL h = 0;
    for ( int i = p, lp = 1; i && lp < MAXK; i = pre[i], ++lp ) {
        ULL r = h += pwr[lp - 1] * a[i];
        for ( int j = q, lq = 1; j && lp + lq <= MAXK; j = nex[j], ++lq ) {
            r = r * BASE + a[j];
            buc[lp + lq][r] += v;
        }
    }
}

int main() {
    n = rint(), m = rint();
    rep ( i, 1, n ) ++buc[1][a[i] = rint()];

    pwr[0] = 1;
    rep ( i, 1, MAXK ) pwr[i] = pwr[i - 1] * BASE;

    for ( int op, i, j; m--; ) {
        op = rint();
        if ( op == 1 ) {
            i = rint(), j = rint();
            nex[i] = j, pre[j] = i;
            contr( i, j, 1 );
        } else if ( op == 2 ) {
            i = rint();
            contr( i, nex[i], -1 );
            pre[nex[i]] = 0, nex[i] = 0;
        } else {
            scanf( "%s %d", str + 1, &i );
            int l = strlen( str + 1 ), ans = 1;
            ULL h = 0;

            rep ( k, 1, i - 1 ) h = h * BASE + ( str[k] ^ '0' );
            rep ( k, i, l ) {
                if ( k > i ) h -= pwr[i - 1] * ( str[k - i] ^ '0' );
                h = h * BASE + ( str[k] ^ '0' );
                ans = mul( ans, buc[i][h] );
            }

            wint( ans ), putchar( '\n' );
        }
    }
    return 0;
}

posted @ 2022-08-15 09:15  Rainybunny  阅读(85)  评论(0编辑  收藏  举报