QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#706844#7512. Almost Prefix ConcatenationDeltaxTL 0ms0kbC++143.9kb2024-11-03 13:39:582024-11-03 13:40:00

Judging History

你现在查看的是最新测评结果

  • [2024-11-03 13:40:00]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-11-03 13:39:58]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mkp make_pair
#define pb push_back
typedef pair <int, int> pii;

inline int read() {
	int x = 0, f = 0;
	char c = getchar();
	while (!isdigit(c)) {if (c == '-') f = 1; c = getchar();}
	while (isdigit(c)) x = (x << 1) + (x << 3) + (c & 15), c = getchar();
	return f? -x : x;
}

const int MAXN = 1e6;
char s[MAXN + 10], t[MAXN + 10];

namespace SAM {
    const int MAXS = MAXN*4 + 10;
        vector <int> G[MAXS];
        //int ch[MAXS][28];
		map <short, int> ch[MAXS];
        int len[MAXS], fa[MAXS], last, tot;
        int extend(int c) {
            int np = ++tot, p = last; last = np;
            len[np] = len[p] + 1; 
            for (; p && ch[p].find(c) == ch[p].end(); p = fa[p]) ch[p][c] = np;
            if (ch[p].find(c) == ch[p].end()) {
                ch[p][c] = np;
                fa[np] = p;
                return np;
            }
            int q = ch[p][c];
            if (len[q] > len[p] + 1) {
                int nq = ++tot; len[nq] = len[p] + 1; fa[nq] = fa[q];
				ch[nq] = ch[q];
                //for (int i = 0; i < 26; ++i) ch[nq][i] = ch[q][i];
                fa[np] = fa[q] = nq;
                for (; ch[p].find(c) != ch[p].end() && ch[p][c] == q; p = fa[p]) ch[p][c] = nq;
            }
            else fa[np] = q;
            return np;
        }

        //ST :: ST<pii> st;
        int siz[MAXS], son[MAXS], top[MAXS], d[MAXS];
        void dfs1(int x) {
            siz[x] = 1; 
            for (auto v : G[x]) {
				//d[v] = d[x] + 1;
                dfs1(v);
                siz[x] += siz[v];
				if (!son[x] || siz[v] > siz[son[x]])
					son[x] = v;
            }
        }
		void dfs2(int x) {
			if (son[x]) {
				top[son[x]] = top[x];
				dfs2(son[x]);
			}
			for (auto v : G[x])
				if (v != son[x]) top[v] = v, dfs2(v);
		}

		int LCA(int x, int y) {
			while (top[x] != top[y]) {
				if (d[top[x]] > d[top[y]]) swap(x, y);
				y = fa[top[y]];
			}
			return d[x] < d[y]? x : y;
		}
        void build() {
			for (int i = 0; i <= tot; ++i)
				ch[i].clear();
            for (int i = 1; i <= tot; ++i)
                G[fa[i]].pb(i);
            dfs1(0);
			dfs2(0);
        }
        void clear() {
    //        st.clear();
            for (int i = 0; i <= tot + 1; ++i) {
           //     memset(ch[i], 0, sizeof(ch[i]));
		   		ch[i].clear();
                len[i] = fa[i] = 0;
				siz[i] = d[i] = son[i] = top[i] = 0;
                G[i].clear();
            }
            last = tot = 0;
        }
        inline int LCP(int x, int y) {return len[LCA(x, y)];} //front
}

int rm[MAXN + 10];
int pos1[MAXN + 10], pos2[MAXN + 10];

const int Mod = 998244353;
inline int add(int u, int v) {
	return (u + v) % Mod;
}
inline int sub(int u, int v) {
	return (u + Mod - v) % Mod;
}

int main() {
	scanf("%s", s + 1);
	scanf("%s", t + 1);
	int n = strlen(s + 1);
	int m = strlen(t + 1);
	for (int i = m; i >= 1; --i)
		pos2[i] = SAM::extend(t[i] - 'a');
	for (int i = n; i >= 1; --i)
		pos1[i] = SAM::extend(s[i] - 'a');
	SAM::build();
	for (int i = 1; i <= n; ++i) {
		rm[i] = SAM::LCP(pos1[i], pos2[1]);
		rm[i] += 1 + SAM::LCP(pos1[i + rm[i] + 1], pos2[1 + rm[i] + 1]);
		rm[i] = min(rm[i], n - i + 1);
		rm[i] = min(rm[i], m);
		rm[i] = i + rm[i] - 1;
	//	cout << rm[i] << " \n"[i == n];
	}
	static int sf[MAXN + 10][3];
	sf[n + 1][0] = 1;
	sf[n + 1][1] = 0;
	sf[n + 1][2] = 0;
	for (int i = n; i >= 1; --i) {
		static int val[3];
		int r = rm[i] + 1;
		int tmp = sub(sf[i + 1][1], sf[r + 1][1]);
		val[0] = sub(sf[i + 1][0], sf[r + 1][0]);
		val[1] = add(tmp, val[0]);
		val[2] = sub(sf[i + 1][2], sf[r + 1][2]);
		val[2] = add(add(val[2], (tmp*2)%Mod), val[0]);
		for (int j = 0; j <= 2; ++j)
			sf[i][j] = add(sf[i + 1][j], val[j]);
	}
	cout << sub(sf[1][2], sf[2][2]) << endl;
	return 0;
}



Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Time Limit Exceeded

input:

ababaab
aba

output:


result: