이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
// Om Namah Shivaya
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
template<typename T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long int ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL)
#define pb push_back
#define endl '\n'
#define sz(a) a.size()
#define setbits(x) __builtin_popcountll(x)
#define ff first
#define ss second
#define conts continue
#define ceil2(x, y) ((x + y - 1) / (y))
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define yes cout << "yes" << endl
#define no cout << "no" << endl
#define rep(i, n) for(int i = 0; i < n; ++i)
#define rep1(i, n) for(int i = 1; i <= n; ++i)
#define rev(i, s, e) for(int i = s; i >= e; --i)
#define trav(i, a) for(auto &i : a)
template<typename T>
void amin(T &a, T b) {
a = min(a, b);
}
template<typename T>
void amax(T &a, T b) {
a = max(a, b);
}
#ifdef LOCAL
#include "debug.h"
#else
#define debug(x) 42
#endif
/*
refs:
edi
if val v is contained in node u, then:
1) the id of the edges on the path from v to u must be increasing (so that v passes through all nodes on the path and eventually comes to u)
2) and the max edge id on the path must be less than the curr query id (otherwise the max edge will never exist during the time of the query, so u and v will never be connected during the time of the query)
rewriting the conditions by including the lca so that it's easier to compute:
v -> u = v -> lca + lca -> u
v -> lca = inc
u -> lca = dec
max(v->lca) < min(u->lca)
max(v->u) < id
*/
const int MOD = 1e9 + 7;
const int N = 1.2e5 + 5;
const int inf1 = int(1e9) + 5;
const ll inf2 = ll(1e18) + 5;
vector<pll> adj[N];
struct lca_algo {
// LCA template (for graphs with 1-based indexing)
int LOG = 1;
vector<int> depth;
vector<vector<int>> up;
vector<vector<int>> mn, mx, inc, dec;
lca_algo() {
}
lca_algo(int n) {
lca_init(n);
}
void lca_init(int n) {
while ((1 << LOG) < n) LOG++;
up = vector<vector<int>>(n + 1, vector<int>(LOG, 1));
depth = vector<int>(n + 1);
mn = vector<vector<int>>(n + 1, vector<int>(LOG, inf1));
mx = vector<vector<int>>(n + 1, vector<int>(LOG, -inf1));
inc = vector<vector<int>>(n + 1, vector<int>(LOG, 1));
dec = vector<vector<int>>(n + 1, vector<int>(LOG, 1));
lca_dfs(1, -1);
}
void lca_dfs(int node, int par) {
for(auto [child, w] : adj[node]) {
if (child == par) conts;
depth[child] = depth[node] + 1;
up[child][0] = node;
rep1(j, LOG - 1) {
up[child][j] = up[up[child][j - 1]][j - 1];
}
mn[child][0] = mx[child][0] = w;
rep1(j,LOG-1){
mn[child][j] = min(mn[child][j-1], mn[up[child][j-1]][j-1]);
mx[child][j] = max(mx[child][j-1], mx[up[child][j-1]][j-1]);
}
inc[child][0] = dec[child][0] = 1;
rep1(j,LOG-1){
inc[child][j] = (inc[child][j-1] & inc[up[child][j-1]][j-1] & mx[child][j-1] < mn[up[child][j-1]][j-1]);
dec[child][j] = (dec[child][j-1] & dec[up[child][j-1]][j-1] & mn[child][j-1] > mx[up[child][j-1]][j-1]);
}
lca_dfs(child, node);
}
}
int lift(int u, int k) {
rep(j, LOG) {
if (k & (1 << j)) {
u = up[u][j];
}
}
return u;
}
int query(int u, int v) {
if (depth[u] < depth[v]) swap(u, v);
int k = depth[u] - depth[v];
u = lift(u, k);
if (u == v) return u;
rev(j, LOG - 1, 0) {
if (up[u][j] != up[v][j]) {
u = up[u][j];
v = up[v][j];
}
}
u = up[u][0];
return u;
}
array<int,4> get(int u, int lca){
int k = depth[u] - depth[lca];
array<int,4> curr = {inf1,-inf1,1,1};
rep(j,LOG){
if(!(k & (1 << j))) conts;
// merge curr with up[u][j]
array<int,4> curr_new;
curr_new[0] = min(curr[0], mn[u][j]);
curr_new[1] = max(curr[1], mx[u][j]);
curr_new[2] = (curr[2] & inc[u][j] & curr[1] < mn[u][j]);
curr_new[3] = (curr[3] & dec[u][j] & curr[0] > mx[u][j]);
curr = curr_new;
u = up[u][j];
}
assert(u == lca);
return curr;
}
int get_dis(int u, int v) {
int lca = query(u, v);
return depth[u] + depth[v] - 2 * depth[lca];
}
bool is_inc(int u, int v, int t){
// is the path from u to v increasing at time t?
int lca = query(u,v);
auto [mn1,mx1,inc1,dec1] = get(u,lca);
auto [mn2,mx2,inc2,dec2] = get(v,lca);
if(inc1 and dec2 and mx1 < mn2 and max(mx1,mx2) < t){
return true;
}
else{
return false;
}
}
};
void solve(int test_case)
{
ll n,k; cin >> n >> k;
vector<array<ll,3>> queries(n+k+5);
rep1(id,n+k-1){
char ch; cin >> ch;
ll t = 0;
if(ch == 'S') t = 1;
else if(ch == 'Q') t = 2;
else t = 3;
if(t <= 2){
ll u,v; cin >> u >> v;
queries[id] = {t, u, v};
if(t == 1){
adj[u].pb({v,id});
adj[v].pb({u,id});
}
}
else{
ll u; cin >> u;
queries[id] = {t, u};
}
}
lca_algo LCA(n);
rep1(id,n+k-1){
auto [t,u,v] = queries[id];
if(t == 1) conts;
if(LCA.is_inc(v,u,id)) yes;
else no;
}
}
int main()
{
fastio;
int t = 1;
// cin >> t;
rep1(i, t) {
solve(i);
}
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
servers.cpp: In member function 'void lca_algo::lca_dfs(int, int)':
servers.cpp:126:94: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses]
126 | inc[child][j] = (inc[child][j-1] & inc[up[child][j-1]][j-1] & mx[child][j-1] < mn[up[child][j-1]][j-1]);
servers.cpp:127:94: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses]
127 | dec[child][j] = (dec[child][j-1] & dec[up[child][j-1]][j-1] & mn[child][j-1] > mx[up[child][j-1]][j-1]);
servers.cpp: In member function 'std::array<int, 4> lca_algo::get(int, int)':
servers.cpp:173:58: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses]
173 | curr_new[2] = (curr[2] & inc[u][j] & curr[1] < mn[u][j]);
servers.cpp:174:58: warning: suggest parentheses around comparison in operand of '&' [-Wparentheses]
174 | curr_new[3] = (curr[3] & dec[u][j] & curr[0] > mx[u][j]);
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |