結果
問題 | No.2020 Sum of Common Prefix Length |
ユーザー | 👑 Nachia |
提出日時 | 2022-07-22 23:07:06 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 184 ms / 2,000 ms |
コード長 | 7,282 bytes |
コンパイル時間 | 1,084 ms |
コンパイル使用メモリ | 95,544 KB |
実行使用メモリ | 67,560 KB |
最終ジャッジ日時 | 2024-07-04 07:46:08 |
合計ジャッジ時間 | 6,956 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 8 ms
19,304 KB |
testcase_01 | AC | 7 ms
19,300 KB |
testcase_02 | AC | 7 ms
19,124 KB |
testcase_03 | AC | 9 ms
19,552 KB |
testcase_04 | AC | 10 ms
19,696 KB |
testcase_05 | AC | 9 ms
19,696 KB |
testcase_06 | AC | 9 ms
19,724 KB |
testcase_07 | AC | 97 ms
60,904 KB |
testcase_08 | AC | 97 ms
61,048 KB |
testcase_09 | AC | 95 ms
61,448 KB |
testcase_10 | AC | 95 ms
61,444 KB |
testcase_11 | AC | 105 ms
60,884 KB |
testcase_12 | AC | 102 ms
60,904 KB |
testcase_13 | AC | 96 ms
60,948 KB |
testcase_14 | AC | 109 ms
60,892 KB |
testcase_15 | AC | 82 ms
66,800 KB |
testcase_16 | AC | 81 ms
67,560 KB |
testcase_17 | AC | 154 ms
59,916 KB |
testcase_18 | AC | 145 ms
60,068 KB |
testcase_19 | AC | 150 ms
60,144 KB |
testcase_20 | AC | 121 ms
60,132 KB |
testcase_21 | AC | 176 ms
60,856 KB |
testcase_22 | AC | 184 ms
59,944 KB |
testcase_23 | AC | 182 ms
59,744 KB |
testcase_24 | AC | 145 ms
60,156 KB |
testcase_25 | AC | 142 ms
60,032 KB |
testcase_26 | AC | 64 ms
47,724 KB |
testcase_27 | AC | 8 ms
19,272 KB |
testcase_28 | AC | 89 ms
63,020 KB |
testcase_29 | AC | 88 ms
63,492 KB |
testcase_30 | AC | 87 ms
62,920 KB |
testcase_31 | AC | 96 ms
60,148 KB |
testcase_32 | AC | 86 ms
60,280 KB |
testcase_33 | AC | 91 ms
60,240 KB |
testcase_34 | AC | 83 ms
63,676 KB |
testcase_35 | AC | 84 ms
63,780 KB |
testcase_36 | AC | 87 ms
63,628 KB |
testcase_37 | AC | 84 ms
64,176 KB |
ソースコード
#include <vector> #include <algorithm> #include <iostream> namespace nachia { struct LinkCutTree { struct S { unsigned int x; }; static S op(S l, S r) { return { l.x + r.x }; } static S e() { return { 0 }; } static void reverseprod(S& x) {} struct F { }; static S mapping(F f, S x) { return x; } static F composition(F f, F x) { return x; } static F id() { return {}; } struct Node { Node* l = 0, * r = 0, * p = 0; S a = e(); S prod = e(); F f = id(); // lazy & 1 : reverse // lazy & 2 : deta int lazy = 0; void prepareDown() { if(lazy & 2){ if(l) { l->a = mapping(f, l->a); l->prod = mapping(f, l->prod); l->f = composition(f, l->f); l->lazy |= 2; } if(r) { r->a = mapping(f, r->a); r->prod = mapping(f, r->prod); r->f = composition(f, r->f); r->lazy |= 2; } f = id(); } if (lazy & 1) { ::std::swap(l, r); if (l) { l->lazy ^= 1; reverseprod(l->prod); } if (r) { r->lazy ^= 1; reverseprod(r->prod); } } lazy = 0; } void prepareUp() { auto res = a; if(l) res = op(l->prod, res); if(r) res = op(res, r->prod); prod = res; } Node** p_parentchild() { if(!p) return nullptr; if(p->l == this) return &p->l; else if(p->r == this) return &p->r; return nullptr; } void rotL() { Node* t = p; Node** parentchild_p = t->p_parentchild(); if(parentchild_p){ *parentchild_p = this; } p = t->p; t->p = this; t->r = l; if(l) l->p = t; l = t; } void rotR() { Node* t = p; Node** parentchild_p = t->p_parentchild(); if(parentchild_p){ *parentchild_p = this; } p = t->p; t->p = this; t->l = r; if(r) r->p = t; r = t; } }; ::std::vector<Node> A; LinkCutTree(int n = 0) { A.resize(n); } LinkCutTree(const ::std::vector<S>& a) : LinkCutTree(a.size()) { for (int i = 0; i < (int)a.size(); i++) A[i].prod = A[i].a = a[i]; } Node* at(int idx) { return &A[idx]; } void splay(Node* c) { c->prepareDown(); while(true) { Node* p = c->p; if(!p) break; Node* pp = p->p; if(pp) pp->prepareDown(); p->prepareDown(); c->prepareDown(); if(p->l == c){ if(!pp){ c->rotR(); } else if(pp->l == p){ p->rotR(); c->rotR(); } else if(pp->r == p){ c->rotR(); c->rotL(); } else{ c->rotR(); } } else if(p->r == c){ if(!pp){ c->rotL(); } else if(pp->r == p){ p->rotL(); c->rotL(); } else if(pp->l == p){ c->rotL(); c->rotR(); } else{ c->rotL(); } } else break; if(pp) pp->prepareUp(); p->prepareUp(); } c->prepareUp(); } void expose(Node* c) { auto p = c; while(p){ splay(p); p = p->p; } p = c; while(p->p){ p->p->r = p; p = p->p; } splay(c); c->r = nullptr; c->prod = (c->l ? op(c->l->prod, c->a) : c->a); } void evert(Node* c) { expose(c); c->lazy ^= 1; reverseprod(c->prod); c->prepareDown(); } void link(Node* c, Node* r) { if(c == r) return; evert(c); evert(r); if(c->p) return; c->p = r; } void cut(Node* c) { expose(c); if(!c->l) return; c->l->p = nullptr; c->l = nullptr; } // [u,v) // post : evert(u) , splayLC(v) Node* between(Node* u, Node* v) { if(u == v) return nullptr; evert(u); expose(v); v->l->prepareDown(); return v->l; } S prod(Node* s, Node* t) { auto resv = between(s, t); if(!resv) return t->a; S res = resv->prod; res = op(res, t->a); return res; } S get(Node* p) { expose(p); return p->a; } void set(Node* p, S x) { expose(p); p->a = x; p->prepareUp(); } }; } #include <iostream> #include <string> #include <vector> #include <algorithm> #include <atcoder/modint> using namespace std; using i32 = int32_t; using u32 = uint32_t; using i64 = int64_t; using u64 = uint64_t; #define rep(i,n) for(int i=0; i<(int)(n); i++) const i64 INF = 1001001001001001001; using modint = atcoder::static_modint<998244353>; int N, Q; vector<string> S; int nx[410000][26]; vector<int> pos; int NN; pair<int, bool> getNext(int p, char c){ int& dst = nx[p][c-'a']; if(dst == -1) return make_pair(dst = NN++, true); return make_pair(dst, false); } int main(){ cin >> N; S.resize(N); rep(i,N) cin >> S[i]; nachia::LinkCutTree lct(410000); cin >> Q; int Z = Q + 1; for(auto& s : S) Z += s.size(); rep(i,Z) rep(t,26) nx[i][t] = -1; NN = 1; pos.assign(N, 0); rep(i,N) for(char c : S[i]){ auto [nx,isnew] = getNext(pos[i], c); if(isnew){ lct.set(lct.at(nx), {1}); lct.link(lct.at(nx), lct.at(pos[i])); } else{ lct.set(lct.at(nx), { lct.get(lct.at(nx)).x + 1 }); } pos[i] = nx; } rep(i,Q){ int t; cin >> t; if(t == 1){ int x; cin >> x; x--; char c; cin >> c; auto [nx,isnew] = getNext(pos[x], c); if(isnew){ lct.set(lct.at(nx), {1}); lct.link(lct.at(nx), lct.at(pos[x])); } else{ lct.set(lct.at(nx), { lct.get(lct.at(nx)).x + 1 }); } pos[x] = nx; } if(t == 2){ int x; cin >> x; x--; auto ans = lct.prod(lct.at(0), lct.at(pos[x])).x; cout << ans << '\n'; } } return 0; } struct ios_do_not_sync{ ios_do_not_sync(){ std::ios::sync_with_stdio(false); std::cin.tie(nullptr); } } ios_do_not_sync_instance;