提交记录 9003


用户 题目 状态 得分 用时 内存 语言 代码长度
sys_con noi18c. 【NOI2018】你的名字 Accepted 100 2.442 s 342464 KB C++ 4.25 KB
提交时间 评测时间
2019-04-01 15:24:44 2020-08-01 01:29:12
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#define MAX_N 500007
#define MAX_T 1000007

char s[MAX_T];
int N, M;
int head[MAX_T], to[MAX_T], nxt[MAX_T], cap;
int lck, bg[MAX_T], ed[MAX_T];
int rt[MAX_T];
int tt[MAX_T * 20], ls[MAX_T * 20], rs[MAX_T * 20], siz;
int mx[MAX_T], pos[MAX_T];

inline void addEdge (int u, int v) {
    nxt[++cap] = head[u];
    head[u] = cap;
    to[cap] = v;
}

void build (int l, int r, int& x, int y, int pos) {
    if (l > r || l > pos || r < pos) return;
    x = ++siz;
    tt[x] = tt[y] + 1;
    if (l == r) return;
    int mid = l + r >> 1;
    if (pos <= mid) rs[x] = rs[y], build(l, mid, ls[x], ls[y], pos);
    if (mid < pos) ls[x] = ls[y], build(mid + 1, r, rs[x], rs[y], pos);
}

struct sam {
    int last, sz, root;
    bool has[MAX_T * 2];

    sam () {
	last = sz = root = 1;
    }

    struct node {
        int fa, mx;
        int go[30];
        node () {}
        node (int mx_) : fa(0), mx(mx_) {
            memset(go, 0, sizeof(go));
        }
    }t[MAX_T * 2];

    inline void init () {
        last = sz = root = 1;
        memset(t[root].go, 0, sizeof(t[root].go));
        t[root].fa = t[root].mx = 0;
	memset(has, false, sizeof(has));
    }

    inline void insert (int c, int idx) {
        int p = last, np = ++sz;
	has[np] = true, pos[np] = idx;
        t[np] = node(t[p].mx + 1);
        while (p && !t[p].go[c]) t[p].go[c] = np, p = t[p].fa;
        if (!p)
            t[np].fa = root;
        else {
            int q = t[p].go[c];
            if (q > MAX_T * 2 || p > MAX_T * 2) exit(1);
            if (t[q].mx == t[p].mx + 1)
                t[np].fa = q;
            else {
                int nq = ++sz;
                t[nq] = node(t[p].mx + 1);
		pos[nq] = pos[q];
                memcpy(t[nq].go, t[q].go, sizeof(t[nq].go));
                t[nq].fa = t[q].fa;
                t[q].fa = t[np].fa = nq;
                while (p && t[p].go[c] == q) t[p].go[c] = nq, p = t[p].fa;
            }
        }
        last = np;
    }

    void dfs (int x) {
        bg[x] = ++lck;
	pos[lck] = x;
	for (int i = head[x]; i; i = nxt[i])
	    dfs(to[i]);
        ed[x] = lck;
    }

    inline void bld () {
        for (int i = 2;i <= sz; ++i) addEdge(t[i].fa, i);
        dfs(root);
        for (int i = 1;i <= lck; ++i)
            if (has[pos[i]]) build(1, N, rt[i], rt[i - 1], t[pos[i]].mx);
            else rt[i] = rt[i - 1];
    }
}t1, t2;

int query (int l, int r, int x, int y, int totl, int totr) {
    if (l > r || l > totr || r < totl) return 0;
    if (totl <= l && r <= totr) return tt[x] - tt[y];
    int mid = l + r >> 1, ans = 0;
    if (totl <= mid) ans += query(l, mid, ls[x], ls[y], totl, totr);
    if (mid < totr) ans += query(mid + 1, r, rs[x], rs[y], totl, totr);
    return ans;
}

inline bool valid (int p, int l, int r) {
    if (!p) return false;
    return query(1, N, rt[ed[p]], rt[bg[p] - 1], l, r) > 0;
}

int main () {
    freopen ("name.in", "r", stdin);
    freopen ("name.out", "w", stdout);
    scanf("%s", s);
    N = strlen(s);
    for (int i = 0;i < N; ++i)
        t1.insert(s[i] - 'a', i);
    t1.bld();
    int Q, l, r;
    scanf("%d", &Q);
    while (Q--) {
        t2.init();
        scanf("%s%d%d", s, &l, &r);
        M = strlen(s);
        for (int i = 0;i < M; ++i) t2.insert(s[i] - 'a', i);
        int lon = 0, p = t1.root;
        for (int i = 0;i < M; ++i) {
	    //printf("%d %d %d %d %d\n", p, lon, l, r, l + lon);
	    while (1) {
	    	if (valid(t1.t[p].go[s[i] - 'a'], l + lon, r)) {
	    	    p = t1.t[p].go[s[i] - 'a'], lon++;
	    	    break;
	    	}
	    	if (lon == 0) break;
	    	lon--;
	    	if (lon == t1.t[t1.t[p].fa].mx) p = t1.t[p].fa;
	    }
	    mx[i] = lon;            
        }
	long long res = 0;
	for (int i = 2;i <= t2.sz; ++i) res += std::max(0, t2.t[i].mx - std::max(t2.t[t2.t[i].fa].mx, mx[pos[i]]));
        for (int i = 2;i <= t2.sz; ++i) mx[i] = 0;
	printf("%lld\n", res);
    }
    return 0;
}
/*
	    if (valid(t1.t[p].go[s[i] - 'a'], l + lon, r))
	        lon++, p = t1.t[p].go[s[i] - 'a'];
	    else {
	        while (p && !valid(t1.t[p].go[s[i] - 'a'], l + lon, r))
	            p = t1.t[p].fa;
	        if (!p)
	            lon = 0, p = t1.root;
	        else
	            lon = t1.t[p].mx + 1, p = t1.t[p].go[s[i] - 'a'];
	    }
	    mx[i] = lon;
*/

CompilationN/AN/ACompile OKScore: N/A

Testcase #111.87 ms2 MB + 108 KBAcceptedScore: 4

Testcase #213.106 ms2 MB + 408 KBAcceptedScore: 4

Testcase #313.583 ms2 MB + 408 KBAcceptedScore: 4

Testcase #465.08 ms2 MB + 908 KBAcceptedScore: 4

Testcase #562.784 ms2 MB + 896 KBAcceptedScore: 4

Testcase #6661.058 ms334 MB + 448 KBAcceptedScore: 4

Testcase #7663.369 ms334 MB + 356 KBAcceptedScore: 4

Testcase #8290.277 ms49 MB + 380 KBAcceptedScore: 4

Testcase #9403.1 ms44 MB + 804 KBAcceptedScore: 4

Testcase #10593.369 ms95 MB + 580 KBAcceptedScore: 4

Testcase #11868.185 ms89 MB + 488 KBAcceptedScore: 4

Testcase #12939.918 ms142 MB + 336 KBAcceptedScore: 4

Testcase #131.364 s135 MB + 964 KBAcceptedScore: 4

Testcase #141.278 s190 MB + 748 KBAcceptedScore: 4

Testcase #151.896 s183 MB + 744 KBAcceptedScore: 4

Testcase #161.63 s239 MB + 168 KBAcceptedScore: 4

Testcase #172.442 s231 MB + 792 KBAcceptedScore: 4

Testcase #181.894 s104 MB + 664 KBAcceptedScore: 4

Testcase #192.009 s148 MB + 564 KBAcceptedScore: 4

Testcase #202.178 s193 MB + 556 KBAcceptedScore: 4

Testcase #212.219 s239 MB + 308 KBAcceptedScore: 4

Testcase #222.328 s239 MB + 116 KBAcceptedScore: 4

Testcase #232.328 s239 MB + 48 KBAcceptedScore: 4

Testcase #242.275 s239 MB + 272 KBAcceptedScore: 4

Testcase #252.213 s239 MB + 316 KBAcceptedScore: 4


Judge Duck Online | 评测鸭在线
Server Time: 2024-05-05 16:03:45 | Loaded in 2 ms | Server Status
个人娱乐项目,仅供学习交流使用