Submission #1093861

#TimeUsernameProblemLanguageResultExecution timeMemory
1093861TymondInside information (BOI21_servers)C++17
2.50 / 100
97 ms39204 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using ld = long double; #define fi first #define se second #define vi vector<int> #define vll vector<long long> #define pii pair<int, int> #define pll pair<long long, long long> #define pb push_back #define mp make_pair #define eb emplace_back #define all(x) (x).begin(), (x).end() #define sz(x) (int)(x).size() mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); mt19937_64 rng64(chrono::steady_clock::now().time_since_epoch().count()); inline int rand(int l,int r){return uniform_int_distribution<int>(l, r)(rng);} inline ll rand(ll l,ll r){return uniform_int_distribution<ll>(l, r)(rng64);} #ifdef DEBUG auto&operator<<(auto&o,pair<auto,auto>p){return o<<"("<<p.first<<", "<<p.second<<")";} auto operator<<(auto&o,auto x)->decltype(x.end(),o){o<<"{";int i=0;for(auto e:x)o<<","+!i++<<e;return o<<"}";} #define debug(X...)cerr<<"["#X"]: ",[](auto...$){((cerr<<$<<"; "),...)<<endl;}(X) #else #define debug(...){} #endif struct custom_hash { static uint64_t splitmix64(uint64_t x) { x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31); } size_t operator()(uint64_t x) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(x + FIXED_RANDOM); } }; struct Query{ char type; int x, y; Query(char nt = 'C', int nx = 0, int ny = 0){ type = nt; x = nx; y = ny; } }; const int MAXN = 3e5 + 7; const int INF = (int)1e9; Query tab[MAXN]; vector<pii> g[MAXN]; int parent[MAXN]; int sz[MAXN]; int base[MAXN]; vector<pii> tree[MAXN]; pii id[MAXN]; int up[MAXN]; int jump[MAXN]; int dep[MAXN]; int n, k; int query1(int v, int l, int p, int a, int b, int d){ if(p < a || b < l){ return INF; } if(a <= l && p <= b){ return tree[d][v].fi; } int mid = (l + p) / 2; return min(query1(2 * v, l, mid, a, b, d), query1(2 * v + 1, mid + 1, p, a, b, d)); } int query2(int v, int l, int p, int a, int b, int d){ if(p < a || b < l){ return 0; } if(a <= l && p <= b){ return tree[d][v].se; } int mid = (l + p) / 2; return max(query2(2 * v, l, mid, a, b, d), query2(2 * v + 1, mid + 1, p, a, b, d)); } int l; void dfs1(int v, int p, int d){ parent[v] = p; dep[v] = d; sz[v] = 1; for(int i = 0; i < sz(g[v]); i++){ if(g[v][i].fi == p){ continue; } up[g[v][i].fi] = g[v][i].se; dfs1(g[v][i].fi, v, d + 1); sz[v] += sz[g[v][i].fi]; if(i > 0 && (g[v][0].fi == p || sz[g[v][0].fi] < sz[g[v][i].fi])){ swap(g[v][0], g[v][i]); } } } void buildTree(int s, int e){ l++; vi path; int akt = e; while(akt != s){ path.pb(akt); akt = parent[akt]; } path.pb(s); reverse(all(path)); base[l] = 1; while(base[l] <= sz(path)){ base[l] *= 2; } for(int i = 0; i < sz(path); i++){ id[path[i]] = {l, i}; } tree[l].assign(2 * base[l] + 5, {INF, 0}); for(int i = 0; i < sz(path); i++){ tree[l][i + base[l]] = {up[path[i]], up[path[i]]}; } for(int i = base[l] - 1; i >= 1; i--){ tree[l][i].fi = min(tree[l][2 * i].fi, tree[l][2 * i + 1].fi); tree[l][i].se = max(tree[l][2 * i].se, tree[l][2 * i + 1].se); } } void dfs2(int v, int s){ jump[v] = s; if(sz(g[v]) == 1 && v != 1){ buildTree(s, v); return; } dfs2(g[v][0].fi, s); for(int i = 1; i < sz(g[v]); i++){ if(g[v][i].fi == parent[v]){ continue; } dfs2(g[v][i].fi, g[v][i].fi); } } bool path(int col, int v, int ourInd){ //cerr << col << ' ' << v << '\n'; int mn = INF; int mx = 0; int aktX = col; int aktY = v; int lst = INF; while(jump[aktX] != jump[aktY]){ if(dep[jump[aktX]] < dep[jump[aktY]]){ swap(aktX, aktY); } //if(jump[aktX] != aktX){ mn = min(mn, query1(1, 0, base[id[aktX].fi] - 1, 0, id[aktX].se, id[aktX].fi)); mx = max(mx, query2(1, 0, base[id[aktX].fi] - 1, 0 + (jump[aktX] == 1), id[aktX].se, id[aktX].fi)); //} mn = min(mn, up[jump[aktX]]); if(jump[aktX] != 1){ mx = max(mx, up[jump[aktX]]); } lst = up[jump[aktX]]; aktX = parent[jump[aktX]]; } if(dep[aktX] > dep[aktY]){ swap(aktX, aktY); } if(aktX != aktY){ mn = min(mn, query1(1, 0, base[id[aktX].fi] - 1, id[aktX].se, id[aktY].se, id[aktX].fi)); mx = max(mx, query2(1, 0, base[id[aktX].fi] - 1, id[aktX].se + (aktX == 1), id[aktY].se, id[aktX].fi)); } //cerr << aktX << ' ' << aktY << ' ' << mn << ' ' << mx << '\n'; if(ourInd < mx){ return 0; } //cerr << mn << '\n'; if(col == aktX){ if(aktX == aktY){ // cerr << lst << '\n'; if(lst > mn){ return 0; } return 1; } // cerr << tree[id[aktX].fi][base[id[aktX].fi] + id[col].se + 1].fi << '\n'; if(tree[id[aktX].fi][base[id[aktX].fi] + id[col].se + 1].fi > mn){ return 0; } return 1; }else{ // cerr << up[col] << '\n'; if(up[col] > mn){ return 0; } return 1; } } int main(){ ios_base::sync_with_stdio(0); cin.tie(NULL); cout.tie(NULL); cin >> n >> k; for(int i = 1; i < n + k; i++){ cin >> tab[i].type >> tab[i].x >> tab[i].y; } for(int i = 1; i < n + k; i++){ if(tab[i].type == 'S'){ g[tab[i].x].pb({tab[i].y, i}); g[tab[i].y].pb({tab[i].x, i}); } } up[1] = INF; dfs1(1, 1, 0); l = 0; dfs2(1, 1); for(int i = 1; i < n + k; i++){ if(tab[i].type != 'Q'){ continue; } if(tab[i].x == tab[i].y){ cout << "yes\n"; continue; } cout << (path(tab[i].y, tab[i].x, i) ? "yes\n" : "no\n"); } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...