QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#731450#9570. Binary Treeucup-team1134#TL 3ms8396kbC++234.4kb2024-11-10 04:19:162024-11-10 04:19:17

Judging History

你现在查看的是最新测评结果

  • [2024-11-10 04:19:17]
  • 评测
  • 测评结果:TL
  • 用时:3ms
  • 内存:8396kb
  • [2024-11-10 04:19:16]
  • 提交

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

result: