QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#851782 | #9570. Binary Tree | BUET_ALUCHASHI# | WA | 0ms | 8548kb | C++17 | 4.1kb | 2025-01-11 00:07:11 | 2025-01-11 00:07:13 |
Judging History
answer
#include <bits/stdc++.h>
#define lli long long
#define plli pair<lli, lli>
#define MAX 200005
const int MOD = 1000000007;
using namespace std;
vector<int> adj[MAX];
vector<bool> is_removed(MAX);
vector<int> subtree_size(MAX);
int ans;
/** DFS to calculate the size of the subtree rooted at `node` */
int get_subtree_size(int node, int parent = -1) {
subtree_size[node] = 1;
for (int child : adj[node]) {
if (child == parent || is_removed[child]) { continue; }
subtree_size[node] += get_subtree_size(child, node);
}
return subtree_size[node];
}
/**
* Returns a centroid (a tree may have two centroids) of the subtree
* containing node `node` after node removals
* @param node current node
* @param tree_size size of current subtree after node removals
* @param parent parent of u
* @return first centroid found
*/
int query(int fir,int sec){
cout<<"? "<<fir<<" "<<sec<<"\n";
cout.flush();
int val;
cin>>val;
return val;
}
int get_centroid(int node, int tree_size, int parent = -1) {
vector<pair<int,int>> szchild;
int sztot=0;
for (int child : adj[node]) {
if(is_removed[child]){
continue;
}
if (child == parent){
continue;
}
if (subtree_size[child] * 2 > tree_size) {
return get_centroid(child, tree_size, node);
}
sztot+=subtree_size[child];
szchild.push_back({subtree_size[child],child});
}
// we got the centroid . now query
if(parent!=-1 && !is_removed[parent]){
szchild.push_back({tree_size-sztot,parent});
}
if(szchild.size()==0){
ans=node;
}else if(szchild.size()==1){
int who=query(node,szchild[0].second);
if(who==0){
ans=node;
is_removed[szchild[0].second]=true;
}else{
is_removed[node]=true;
ans=szchild[0].second;
}
// cout<<"here 1\n";
}else if(szchild.size()==3){
// cout<<"here 3\n";
sort(szchild.begin(),szchild.end());
int who=query(szchild[1].second,szchild[2].second);
if(who==1){
is_removed[szchild[1].second]=true;
is_removed[szchild[2].second]=true;
}else if(who==0){
is_removed[node]=true;
is_removed[szchild[2].second]=true;
}else{
is_removed[node]=true;
is_removed[szchild[1].second]=true;
}
}else if(szchild.size()==2){
// cout<<"here 2\n";
int who=query(szchild[0].second,szchild[1].second);
if(who==1){
is_removed[szchild[1].second]=true;
is_removed[szchild[0].second]=true;
ans=node;
}else if(who==0){
is_removed[node]=true;
is_removed[szchild[1].second]=true;
}else{
is_removed[node]=true;
is_removed[szchild[0].second]=true;
}
}
return node;
}
/** Build up the centroid decomposition recursively */
void build_centroid_decomp(int node = 0) {
int centroid = get_centroid(node, get_subtree_size(node));
// do something
// is_removed[centroid] = true;
for (int child : adj[centroid]) {
if (is_removed[child]) { continue; }
build_centroid_decomp(child);
if(ans!=-1){
break;
}
}
}
int main(){
// ios::sync_with_stdio(0);
// cin.tie(0);cout.tie(0);
int t=1;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=0;i<=n;i++){
adj[i].clear();
is_removed[i]=0;
subtree_size[i]=0;
}
ans=-1;
for(int i=1;i<=n;i++){
int l,r;
cin>>l>>r;
if(l!=0){
adj[i].push_back(l);
adj[l].push_back(i);
}
if(r!=0){
adj[i].push_back(r);
adj[r].push_back(i);
}
}
build_centroid_decomp(1);
cout<<"! "<<ans<<"\n";
cout.flush();
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 8548kb
input:
2 5 0 0 1 5 2 4 0 0 0 0 2
output:
? 1 3 ! 5
result:
wrong answer There are 2 candidates. (test case 1)