#include <bits/stdc++.h>
#define tt cin.tie(0), cout.tie(0), ios_base::sync_with_stdio(0)
#define fo freopen((NAME+".INP").c_str(), "r", stdin), freopen((NAME+".OUT").c_str(), "w", stdout)
#define ll long long
#define ull unsigned long long
#define i128 __int128
#define db long double
#define sz(a) ((int)(a).size())
#define pb emplace_back
#define pf emplace_front
#define pob pop_back
#define pof pop_front
#define lb lower_bound
#define ub upper_bound
#define fi first
#define se second
#define ins emplace
#define mp make_pair
using namespace std;
const int MOD = 1e9+7, MAXN = 3e5+5;
const string NAME = "";
int n,k,q[MAXN],rs[MAXN];
vector<int> query[MAXN];
vector<pair<int,pair<int,int>>> query1;
vector<pair<int,int>> adj[MAXN];
namespace sub1{
int par[MAXN][20],MAX[MAXN][20],depth[MAXN],edge[MAXN];
bool ok[MAXN][20],ok2[MAXN][20];
void dfs(int u){
for(pair<int,int>& e : adj[u]){
if(e.fi==par[u][0]) continue;
edge[e.fi]=e.se;
depth[e.fi]=depth[u]+1, par[e.fi][0]=u, MAX[e.fi][0]=e.se, ok[e.fi][0]=ok2[e.fi][0]=1;
for(int i = 1; i<=__lg(n); ++i){
par[e.fi][i]=par[par[e.fi][i-1]][i-1], MAX[e.fi][i]=max(MAX[e.fi][i-1],MAX[par[e.fi][i-1]][i-1]);
ok[e.fi][i]=ok[e.fi][i-1]&ok[par[e.fi][i-1]][i-1]&(MAX[e.fi][i-1]<MAX[par[e.fi][i-1]][i-1]);
ok2[e.fi][i]=ok2[e.fi][i-1]&ok2[par[e.fi][i-1]][i-1]&(MAX[e.fi][i-1]>MAX[par[e.fi][i-1]][i-1]);
}
dfs(e.fi);
}
}
int lift(int x, int k){
for(int i = 0; i<=__lg(n); ++i)
if((k>>i)&1) x=par[x][i];
return x;
}
int LCA(int x, int y){
if(depth[x]!=depth[y]){
if(depth[x]<depth[y]) swap(x,y);
x=lift(x,depth[x]-depth[y]);
}
if(x==y) return x;
for(int i = __lg(n); i>=0; --i)
if(par[x][i]!=par[y][i]) x=par[x][i], y=par[y][i];
return par[x][0];
}
void solve(){
dfs(1);
for(pair<int,pair<int,int>>& p : query1){
int x=p.se.fi, y=p.se.se, lca=LCA(x,y), maxX=0, maxY=0;
bool good=1;
for(int i = __lg(n); i>=0; --i){
if(depth[par[x][i]]>depth[lca]) good&=ok[x][i], maxX=max(maxX,MAX[x][i]), x=par[x][i];
if(depth[par[y][i]]>depth[lca]) good&=ok2[y][i], maxY=max(maxY,MAX[y][i]), y=par[y][i];
}
if(x!=lca) good&=ok[x][0], maxX=max(maxX,MAX[x][0]);
if(y!=lca) good&=ok2[y][0], maxY=max(maxY,MAX[y][0]), good&=maxX<edge[y];
if(good&&max(maxX,maxY)<p.fi) rs[p.fi]=1;
}
}
}
namespace sub2{
int m,d=0,cnt=0,sz[MAXN],bit[MAXN];
bool del[MAXN];
void dfsSZ(int u, int par){
sz[u]=1;
for(pair<int,int>& e : adj[u])
if(e.fi!=par&&!del[e.fi]) dfsSZ(e.fi,u), sz[u]+=sz[e.fi];
}
int Centroid(int u, int par, int N){
for(pair<int,int>& e : adj[u])
if(e.fi!=par&&!del[e.fi]&&sz[e.fi]>N) return Centroid(e.fi,u,N);
return u;
}
void update(int pos, int val){
while(pos<=m) bit[pos]+=val, pos+=pos&-pos;
}
int getsum(int pos){
int rs=0;
while(pos>0) rs+=bit[pos], pos-=pos&-pos;
return rs;
}
void dfsAnswer(int u, int dist){
for(int& i : query[u]){
if(i<d) continue;
rs[i]+=getsum(i)+1;
}
for(pair<int,int>& e : adj[u])
if(!del[e.fi]&&dist>e.se) dfsAnswer(e.fi,e.se);
}
void dfsUpdate(int u, int dist, int val){
if(val>0) cnt+=val;
update(dist,val);
for(pair<int,int>& e : adj[u])
if(!del[e.fi]&&dist<e.se) dfsUpdate(e.fi,e.se,val);
}
void CentroidDecomposition(int u){
dfsSZ(u,0);
int root=Centroid(u,0,sz[u]>>1);
cnt=0;
for(pair<int,int>& e : adj[root])
if(!del[e.fi]) d=e.se, dfsAnswer(e.fi,e.se), dfsUpdate(e.fi,e.se,1);
for(int& i : query[root])
rs[i]+=getsum(i)+1;
for(pair<int,int>& e : adj[root])
if(!del[e.fi]) dfsUpdate(e.fi,e.se,-1);
del[root]=1;
for(pair<int,int>& e : adj[root])
if(!del[e.fi]) CentroidDecomposition(e.fi);
}
bool cmp(pair<int,int>& a, pair<int,int>& b){
return a.se>b.se;
}
void solve(){
m=n+k-1;
for(int i = 1; i<=n; ++i)
sort(adj[i].begin(),adj[i].end(),cmp);
CentroidDecomposition(1);
}
}
int main()
{
tt;
if(fopen((NAME + ".INP").c_str(), "r")) fo;
cin >> n >> k;
for(int i = 1; i<=n+k-1; ++i){
char type;
int x,y;
cin >> type;
if(type=='S'){
cin >> x >> y;
adj[x].pb(y,i), adj[y].pb(x,i);
}else if(type=='Q'){
cin >> x >> y;
q[i]=1, query1.pb(i,mp(y,x));
}else{
cin >> x;
query[x].pb(i), q[i]=2;
}
}
sub1::solve();
sub2::solve();
for(int i = 1; i<=n+k-1; ++i){
if(q[i]==1) cout << (rs[i]==0 ? "no\n" : "yes\n");
else if(q[i]==2) cout << rs[i] << "\n";
}
}
Compilation message (stderr)
servers.cpp: In function 'int main()':
servers.cpp:3:19: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
3 | #define fo freopen((NAME+".INP").c_str(), "r", stdin), freopen((NAME+".OUT").c_str(), "w", stdout)
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
servers.cpp:135:45: note: in expansion of macro 'fo'
135 | if(fopen((NAME + ".INP").c_str(), "r")) fo;
| ^~
servers.cpp:3:63: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
3 | #define fo freopen((NAME+".INP").c_str(), "r", stdin), freopen((NAME+".OUT").c_str(), "w", stdout)
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
servers.cpp:135:45: note: in expansion of macro 'fo'
135 | if(fopen((NAME + ".INP").c_str(), "r")) fo;
| ^~| # | 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... |