题目链接:https://codeforces.com/contest/1592/problem/D
一般交互题常见的思路 1是二分 2是分块
这道题可以先跑一遍欧拉序,将结点保存在a数组内,之后我们就可以二分a数内连续的一端(这个连续的一段就代表着树内连续的一条边) ,找出的l,r就是题目的答案。
代码如下:
#includeusing namespace std; #define rep(x, y, z) for (int x = y; x <= z; x++) #define dec(x, y, z) for (int x = y; x >= z; x--) const int N = 10010, mod = 1e9 + 7; const double expp = 1e-10; typedef long long ll; //------------------------ int n; vector G[N]; vector ve; int a[N]; int cnt; void add(int a,int b){ G[a].push_back(b); } void dfs(int u,int fa){ for(auto v:G[u]){ if(v == fa) continue; a[++cnt] = v; dfs(v,u); a[++cnt] = u; } } int query(){ sort(ve.begin(),ve.end()); ve.erase(unique(ve.begin(),ve.end()),ve.end()); cout<<"? "<<(int)ve.size()<<" "; rep(i,0,(int)ve.size()-1) cout< >ans; return ans; } int main(){ cin>>n; rep(i,1,n-1){ int u,v; cin>>u>>v; add(u,v); add(v,u); } a[++cnt] = 1; dfs(1,0); rep(i,1,cnt) ve.push_back(a[i]); int maxx = query(); int l=1,r = cnt; while(l+1 > 1; ve.clear(); rep(i,l,mid) ve.push_back(a[i]); if(query() < maxx ) l = mid; else r = mid; } cout<<"! "<



