QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#758013 | #9570. Binary Tree | Eureka | WA | 2ms | 3876kb | C++14 | 5.5kb | 2024-11-17 15:07:54 | 2024-11-17 15:07:55 |
Judging History
answer
//
// Created by 16429 on 2024/11/17.
//
#include "bits/stdc++.h"
using namespace std;
const int N = 3e5+ 50;
struct node{
int v,nt;
};
struct Tree{
vector<int> head,id;
vector<node> ed;
vector<int> sz;
int tot;
int n;
void init(int x){
tot = 0;
n = x;
ed = vector<node>(2*(n+1),{0,0});
sz = id = head = vector<int>(n+1,0);
}
void add_edge(int u,int v){
ed[++tot] = {v,head[u]};
head[u] = tot;
}
};
int sz[N], // 这个节点的「大小」(所有子树上节点数 + 该节点)
weight[N], // 这个节点的「重量」,即所有子树「大小」的最大值
centroid[2]; // 用于记录树的重心(存的是节点编号)
void GetCentroid(int cur, int fa, Tree &tre) { // cur 表示当前节点 (current)
sz[cur] = 1;
weight[cur] = 0;
for (int i = tre.head[cur]; i; i = tre.ed[i].nt) {
if (tre.ed[i].v != fa) { // e[i].to 表示这条有向边所通向的节点。
GetCentroid(tre.ed[i].v, cur, tre);
sz[cur] += sz[tre.ed[i].v];
weight[cur] = max(weight[cur], sz[tre.ed[i].v]);
}
}
weight[cur] = max(weight[cur], tre.n - sz[cur]);
if(weight[cur]<weight[centroid[0]]){
centroid[0] = cur;
}
}
int getzhong(Tree &tre){
for (int i = 0; i <= tre.n; ++i) {
sz[i] = weight[i] = centroid[0] = 0;
}
weight[0] = 1e9;
GetCentroid(1, 0, tre);
return centroid[0];
}
int gtsz(int nw,int fa,Tree &tre){
int res = 1;
for(int i= tre.head[nw]; i ; i = tre.ed[i].nt){
int v = tre.ed[i].v;
if(v==fa)continue;
res += gtsz(v,nw,tre);
}
tre.sz[nw] = res;
return res;
}
void cpt(int nw,int fa,Tree &tre,Tree &t2,int &ct,int t2f){
for(int i= tre.head[nw]; i ; i = tre.ed[i].nt){
int v = tre.ed[i].v;
if(v==fa)continue;
t2.id[++ct] = tre.id[v];
t2.add_edge(t2f,ct);
t2.add_edge(ct,t2f);
int uu = ct;
cpt(v,nw,tre,t2,ct,uu);
}
}
void copyTree(Tree& t1,Tree& t2,int nw,int fa,vector<int> &bz){//吧t1的nw的子树给t2
int sz = 1;
auto fd = [](vector<int> &vc,int x){
for(auto it:vc){
if(it==x)return 1;
}
return 0;
};
for(int i= t1.head[nw]; i ; i = t1.ed[i].nt){
int v = t1.ed[i].v;
if(v==fa)continue;
if(fd(bz,v))continue;
sz += gtsz(v,nw,t1);
}
t2.init(sz);
int ct = 1;
t2.id[1] = t1.id[nw];
for(int i= t1.head[nw]; i ; i = t1.ed[i].nt){
int v = t1.ed[i].v;
if(v==fa)continue;
if(fd(bz,v))continue;
t2.id[++ct] = t1.id[v];
t2.add_edge(1,ct);
t2.add_edge(ct,1);
int uu = ct;
cpt(v,nw,t1,t2,ct,uu);
}
}
int qe(int u,int v,Tree &tre){
cout<<"? "<<tre.id[u]<<' '<<tre.id[v]<<endl;
fflush(stdout);
int res;cin>>res;
return res;
}
int querry(Tree &tre){
if(tre.n==1){
return tre.id[1];
}
int zx = getzhong(tre);
vector<int> sn;
gtsz(zx,0,tre);
for(int i= tre.head[zx]; i ; i = tre.ed[i].nt){
sn.push_back(tre.ed[i].v);
}
sort(sn.begin(),sn.end(),[&tre](int a,int b){
return tre.sz[a]>tre.sz[b];
});
if(sn.size()==1){
Tree t2;
int uu = qe(zx,sn[0],tre);
if(uu==0){
return tre.id[zx];
}
vector<int> by;
copyTree(tre,t2,sn[0],zx,by);
return querry(t2);
}else if(sn.size()==2){
int uu = qe(sn[0],sn[1],tre);
if(uu==1)return tre.id[zx];
if(uu==2)swap(sn[0],sn[1]);
vector<int> bz;
Tree t2;
copyTree(tre,t2,sn[0],zx,bz);
return querry(t2);
}else if(sn.size()==3){
int uu = qe(sn[0],sn[1],tre);
if(uu==1){
vector<int> bz;bz.push_back(sn[1]);bz.push_back(sn[0]);
Tree t2;
copyTree(tre,t2,zx,0,bz);
return querry(t2);
}
if(uu==0){
vector<int> bz;
Tree t2;
copyTree(tre,t2,sn[0],zx,bz);
return querry(t2);
}
if(uu==2){
vector<int> bz;
Tree t2;
copyTree(tre,t2,sn[1],zx,bz);
return querry(t2);
}
}else if(sn.size()==0){
return tre.id[zx];
}
return -1;
}
void work(int shu){
int n;cin>>n;
Tree tre;
tre.init(n);
if(shu)cout<<n<<'\n';
for(int i = 1; i<= n ; ++i){
int l;cin>>l;if(shu)cout<<l;
if(l)tre.add_edge(i,l),tre.add_edge(l,i);
cin>>l;if(shu)cout<<l;
if(l)tre.add_edge(i,l),tre.add_edge(l,i);
}
for(int i = 1; i <= n ;++i)tre.id[i] = i;
int res = querry(tre);
cout<<"! "<<res<<endl;
fflush(stdout);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int t;cin>>t;
for(int i = 1; i<= t;++i){
work(i==17);
}
return 0;
}
/*
1
7
0 0
0 0
2 0
1 5
3 6
0 0
0 4
*/
/*
1
10
2 3
0 0
4 5
6 0
0 7
8 9
10 0
0 0
0 0
0 0
*/
/*
1
20
2 3
4 5
6 7
8 9
10 11
12 13
14 15
0 0
16 0
0 17
0 0
18 0
0 0
0 19
0 0
0 0
0 0
0 0
20 0
0 0
*/
/*
1
15
2 0
3 0
4 15
5 0
6 0
7 0
8 0
9 0
10 0
11 0
12 0
13 0
14 0
0 0
0 0
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3800kb
input:
2 5 0 0 1 5 2 4 0 0 0 0 1 0 2 0 2 0 0 2
output:
? 3 5 ? 1 2 ! 1 ? 2 1 ! 1
result:
ok OK (2 test cases)
Test #2:
score: -100
Wrong Answer
time: 2ms
memory: 3876kb
input:
5555 8 2 0 8 6 0 0 3 0 0 0 7 0 0 0 5 4 0 0 2 8 0 0 1 4 2 0 0 0 7 8 0 0 3 0 6 0 0 1 0 8 5 8 0 0 1 7 0 0 0 0 4 2 0 0 6 0 0 0 2 5 4 5 3 1 0 0 0 0 0 0 0 2 8 0 0 0 0 5 6 0 0 1 4 2 0 3 8 0 0 0 0 5 3 0 5 1 0 0 0 0 4 0 0 2 5 5 0 0 0 0 0 3 0 2 4 0 0 3 3 0 1 0 0 0 2 2 2 0 0 0 0 3 2 3 0 0 0 0 2 10 2 8 9 7 0 0 ...
output:
? 2 4 ? 2 7 ? 1 2 ! 2 ? 3 5 ? 1 4 ? 3 2 ! 3 ? 1 6 ? 1 7 ? 5 1 ! 1 ? 2 5 ? 3 2 ! 2 ? 5 7 ? 1 4 ! 1 ? 1 5 ? 3 1 ! 1 ? 4 2 ? 3 4 ! 3 ? 2 3 ! 3 ? 2 1 ! 2 ? 3 2 ! 2 ? 2 6 ? 1 9 ? 10 9 ! 9 ? 2 1 ! 2 ? 9 5 ? 9 6 ? 1 9 ! 1 ? 5 8 ? 7 1 ? 5 3 ! 5 ? 9 3 ? 1 7 ? 9 2 ! 9 ? 2 1 ! 1 7 00002051360040? 4 3
result:
wrong answer Token parameter [name=op] equals to "7", doesn't correspond to pattern "[?!]{1,1}" (test case 17)