結果
問題 | No.2020 Sum of Common Prefix Length |
ユーザー |
|
提出日時 | 2022-07-22 20:41:41 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 207 ms / 2,000 ms |
コード長 | 2,069 bytes |
コンパイル時間 | 4,842 ms |
コンパイル使用メモリ | 260,172 KB |
最終ジャッジ日時 | 2025-01-30 11:51:06 |
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 38 |
ソースコード
#include<bits/stdc++.h>#include<atcoder/all>using namespace std;using namespace atcoder;#define emb emplace_backusing ll = long long;class EulerTour{int N;vector<int> in,out;fenwick_tree<int> B_v;public:EulerTour(vector<vector<int>> &G):N(G.size()),in(N),out(N),B_v(N*2){int f = 0,cnt = 0;vector<int> itr(N),par(N);par[f] = -1;while(f != -1){if(itr[f] == 0) in[f] = cnt++;if(itr[f] == G[f].size()){out[f] = cnt++;f = par[f];continue;}par[G[f][itr[f]]] = f;f = G[f][itr[f]++];}}void add(int p,int num=1){B_v.add(in[p],num);B_v.add(out[p],-num);}int query(int p){return B_v.sum(0,in[p]+1);}};int main(){cin.tie(0);ios::sync_with_stdio(false);//入力int N;cin >> N;vector<string> S(N);for(string &s:S) cin >> s;int Q;cin >> Q;vector<int> T(Q),X(Q);vector<char> C(Q);//Tはクエリのタイプfor(int i=0;i<Q;i++){cin >> T[i] >> X[i];X[i]--;if(T[i] == 1) cin >> C[i];}//クエリ全処理後のTrie木をつくるvector<vector<int>> path(N,vector<int>({0}));//各文字列の文字ごとのnodeのindexint V = 1;vector<vector<int>> nex(1,vector<int>(26,-1));vector<string> S2 = S;for(int i=0;i<Q;i++){if(T[i] == 1) S2[X[i]] += C[i];}for(int i=0;i<N;i++){int now_node = 0;for(char c:S2[i]){int z = c-'a';if(nex[now_node][z] == -1){nex[now_node][z] = V++;nex.emplace_back(vector<int>(26,-1));}now_node = nex[now_node][z];path[i].emplace_back(now_node);}}//ただの根付き木にするvector<vector<int>> G(V);for(int i=0;i<V;i++){for(int j=0;j<26;j++){if(nex[i][j] != -1) G[i].emplace_back(nex[i][j]);}}EulerTour Eul(G);for(int i=0;i<N;i++){for(int j=0;j<S[i].size();j++) Eul.add(path[i][j+1]);}for(int i=0;i<Q;i++){if(T[i] == 1){S[X[i]] += C[i];Eul.add(path[X[i]][S[X[i]].size()]);}else cout << Eul.query(path[X[i]][S[X[i]].size()]) << "\n";}}