QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#731450 | #9570. Binary Tree | ucup-team1134# | TL | 3ms | 8396kb | C++23 | 4.4kb | 2024-11-10 04:19:16 | 2024-11-10 04:19:17 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define vi vector<int>
#define vl vector<ll>
#define vii vector<pair<int,int>>
#define vll vector<pair<ll,ll>>
#define vvi vector<vector<int>>
#define vvl vector<vector<ll>>
#define vvii vector<vector<pair<int,int>>>
#define vvll vector<vector<pair<ll,ll>>>
#define vst vector<string>
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pb push_back
#define all(x) (x).begin(),(x).end()
#define mkunique(x) sort(all(x));(x).erase(unique(all(x)),(x).end())
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=300005,INF=15<<26;
bool alive[MAX];
//重心分解(使える版)
struct edge{
int to;
int length;
};
int C=-1;
vector<edge> G[MAX];
bool centroid[MAX];
int subtree_size[MAX];
int centpar[MAX];
int compute_subtree_size(int u,int p){
int c=1;
for(auto a:G[u]){
if(a.to==p||centroid[a.to]) continue;
if(!alive[a.to]) continue;
c+=compute_subtree_size(a.to,u);
}
return subtree_size[u]=c;
}
pair<int,int> search_centroid(int u,int p,int t){
pair<int,int> res={INF,-1};
int s=1,m=0;
for(auto a:G[u]){
if(a.to==p||centroid[a.to]) continue;
res=min(res,search_centroid(a.to,u,t));
m=max(m,subtree_size[a.to]);
s+=subtree_size[a.to];
}
m=max(m,t-s);
res=min(res,{m,u});
return res;
}
void solve_subproblem(int u,int p){
compute_subtree_size(u,-1);
int s=search_centroid(u,-1,subtree_size[u]).second;
centroid[s]=1;
if(C==-1) C=s;
centpar[s]=p;
for(auto a:G[s]){
if(centroid[a.to]){
continue;
}
solve_subproblem(a.to,s);
}
centroid[s]=0;
}
int dis[MAX][2];
void BFS(int u,int t){
for(int i=0;i<MAX;i++){
dis[i][t]=INF;
}
dis[u][t]=0;
queue<int> Q;
while(!Q.empty()){
int u=Q.front();Q.pop();
for(auto e:G[u]){
if(alive[e.to]&&chmin(dis[e.to][t],dis[u][t]+1)) Q.push(e.to);
}
}
}
int main(){
int Q;cin>>Q;
while(Q--){
int N;cin>>N;
for(int i=0;i<N;i++){
G[i].clear();
alive[i]=true;
centroid[i]=false;
centpar[i]=0;
}
for(int i=0;i<N;i++){
int a,b;cin>>a>>b;
if(a){
G[i].pb({a-1,1});
G[a-1].pb({i,1});
}
if(b){
G[i].pb({b-1,1});
G[b-1].pb({i,1});
}
}
while(1){
vi V;
for(int i=0;i<N;i++){
if(alive[i]) V.pb(i);
}
if(si(V)==1){
cout<<"! "<<V[0]+1<<endl;
break;
}
if(si(V)==2){
cout<<"? "<<V[0]+1<<" "<<V[1]+1<<endl;
int t;cin>>t;
if(t==0){
cout<<"! "<<V[0]+1<<endl;
break;
}else{
cout<<"! "<<V[1]+1<<endl;
break;
}
}
C=-1;
compute_subtree_size(V[0],-1);
int s=search_centroid(V[0],-1,si(V)).se;
compute_subtree_size(s,-1);
vii X;
for(auto e:G[s]){
if(alive[e.to]) X.pb(mp(subtree_size[e.to],e.to));
}
sort(all(X));
reverse(all(X));
cout<<"? "<<X[0].se+1<<" "<<X[1].se+1<<endl;
BFS(X[0].se,0);
BFS(X[1].se,1);
int c;cin>>c;
for(int i=0;i<N;i++){
if(alive[i]){
if(dis[i][0]<dis[i][1]){
if(c!=0) alive[i]=false;
}
if(dis[i][0]==dis[i][1]){
if(c!=1) alive[i]=false;
}
if(dis[i][0]>dis[i][1]){
if(c!=2) alive[i]=false;
}
}
}
}
}
}
详细
Test #1:
score: 100
Accepted
time: 3ms
memory: 8396kb
input:
2 5 0 0 1 5 2 4 0 0 0 0 1 0 2 0 2 0 0 2
output:
? 3 5 ? 2 1 ! 2 ? 1 2 ! 2
result:
ok OK (2 test cases)
Test #2:
score: -100
Time Limit Exceeded
input:
5555 8 2 0 8 6 0 0 3 0 0 0 7 0 0 0 5 4 0
output:
? 8 6 ! 8