제출 #865854

#제출 시각아이디문제언어결과실행 시간메모리
865854AbdelmagedNourInside information (BOI21_servers)C++17
100 / 100
2920 ms54636 KiB
#include <bits/stdc++.h> #pragma GCC optimize("Ofast,unroll-loops") using namespace std; typedef long long ll; const int N=250005,SQ=500; vector<vector<pair<int,int>>>adj(N); vector<int>cur_adj[N],order; int in[N],out[N],dep[N],p[N][18],val[N],max_inc[N],max_dec[N],T; void init_dfs(int v,int par){ in[v]=++T;order.push_back(v); p[v][0]=par; for(int i=1;i<18;i++)p[v][i]=p[p[v][i-1]][i-1]; max_inc[v]=max_dec[v]=par; if(val[v]<val[par])max_inc[v]=max_inc[par]; else max_dec[v]=max_dec[par]; for(auto&e:adj[v]){ int u=e.first,w=e.second; if(u==par)continue; dep[u]=dep[v]+1; val[u]=w; init_dfs(u,v); } out[v]=T; } bool anc(int v,int u){ return in[v]<=in[u]&&out[u]<=out[v]; } int max_in_path(int u,int v){ if(anc(u,v))return val[v]; int pu=u,pv=v; for(int i=17;i>=0;i--){ if(!anc(p[pu][i],v))pu=p[pu][i]; if(!anc(p[pv][i],u))pv=p[pv][i]; } if(p[pu][0]==v)return val[pu]; return val[pu]<val[pv]?val[v]:INT_MAX; } bool can_reach(int u,int v,int Time){ if(u==v)return 1; if((!anc(max_inc[u],v))||(!anc(max_dec[v],u)))return 0; if(!anc(v,u)&&val[v]>Time)return 0; return max_in_path(u,v)<=Time; } int dp_down[N],dp_up[N],dp[N],vis[N]; void dfs_down(int v,int par){ if(vis[v])return; vis[v]=1; dp_down[v]=dp[v]=1; for(auto&u:cur_adj[v]){ if(u==par)continue; dfs_down(u,v); if(val[u]>val[v])dp_down[v]+=dp_down[u]; dp[v]+=dp_down[u]; } } void dfs_up(int v,int par,int sum=0){ dp_up[v]=sum+(par!=v); if(val[par]>val[v])dp_up[v]+=dp_up[par]; dp[v]+=dp_up[v]; sum=0; for(int i=cur_adj[v].size()-1;i>=0;i--){ int u=cur_adj[v][i]; if(u==par)continue; dfs_up(u,v,sum); sum+=dp_down[u]; } } void reclac(){ memset(vis+1,0,int(order.size())*sizeof(vis[1])); for(auto&u:order){ if(vis[u])continue; dfs_down(u,u); dfs_up(u,u); } } char op[N]; int A[N],B[N]; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int n,q; cin>>n>>q; for(int i=1;i<n+q;i++){ cin>>op[i]; if(op[i]=='S'){ cin>>A[i]>>B[i]; adj[A[i]].push_back({B[i],i}); adj[B[i]].push_back({A[i],i}); } if(op[i]=='Q')cin>>A[i]>>B[i]; if(op[i]=='C')cin>>A[i]; } init_dfs(1,1); fill(dp+1,dp+n+1,1); int cnt=0; vector<int>edges; for(int i=1;i<n+q;i++){ if(cnt==SQ)reclac(),cnt=0,edges.clear(); if(op[i]=='S'){ edges.push_back(i); cur_adj[A[i]].push_back(B[i]); cur_adj[B[i]].push_back(A[i]); cnt++; }else if(op[i]=='Q')cout<<(can_reach(B[i],A[i],i)?"yes\n":"no\n"); else{ int res=dp[A[i]]; for(auto&e:edges){ int u=A[e],v=B[e]; if(val[u]!=e)swap(u,v); if(!anc(u,A[i])&&can_reach(A[i],u,i))res++; else if(anc(u,A[i])&&can_reach(A[i],v,i))res++; } cout<<res<<"\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...