結果
| 問題 |
No.2020 Sum of Common Prefix Length
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2022-04-17 20:50:51 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 193 ms / 2,000 ms |
| コード長 | 1,976 bytes |
| コンパイル時間 | 16,839 ms |
| コンパイル使用メモリ | 330,300 KB |
| 実行使用メモリ | 74,200 KB |
| 最終ジャッジ日時 | 2025-01-28 05:40:11 |
| 合計ジャッジ時間 | 24,809 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 38 |
ソースコード
#include<bits/stdc++.h>
#include<atcoder/all>
using namespace std;
using namespace atcoder;
#define emb emplace_back
using ll = long long;
class EulerTour{
int N,cnt;
vector<int> in,out;
fenwick_tree<ll> B_v;
void dfs(int p,vector<vector<int>> &G){
in[p] = cnt++;
for(int nex:G[p]) dfs(nex,G);
out[p] = cnt++;
}
public:
EulerTour(vector<vector<int>> &G):N(G.size()),cnt(0),in(N),out(N),B_v(N*2){dfs(0,G);}
void add(int p,ll num=1){B_v.add(in[p],num);B_v.add(out[p],-num);}
ll 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のindex
vector<char> node({0});
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] = node.size();
node.emplace_back(c);
nex.emplace_back(vector<int>(26,-1));
}
now_node = nex[now_node][z];
path[i].emplace_back(now_node);
}
}
//ただの根付き木にする
int V = node.size();
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";
}
}