AFO

CF1129E

CF1129E

以1为根,n次可以找出所有子树大小

按照子树大小排序保证x的儿子都在x前面

每次二分找x最右边的儿子,找完打个标记


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

const int M = 1000001;
int n,m,k,a[M],d[M];

struct vv
{
	int s,x;
} t[M];

bool cmp(vv a,vv b){return a.s<b.s;}

int main()
{
	scanf("%d",&n);
	if(n==2)
	{
		printf("ANSWER\n1 2\n"); fflush(stdout);
		return 0;
	}
	for(int i=2;i<=n;i++)
	{
		printf("1\n1\n%d\n",n-2);
		for(int j=2;j<=n;j++)if(i!=j) printf("%d ",j);
		printf("\n%d\n",i); fflush(stdout);
		scanf("%d",&k);
		t[i].s=k,t[i].x=i;
	}
	t[1].s=n,t[1].x=1;
	sort(t+1,t+1+n,cmp);
	for(int i=1;i<n;i++) if(t[i].s)
	{
		int sz=t[i].s;
		while(sz)
		{
			int l=1,r=i-1,mid;
			while(l<r)
			{
				mid=(l+r+1)>>1; int S=0; k=0;
				for(int j=mid;j<=r;j++) if(t[j].x) S++;
				if(S)
				{
					printf("1\n1\n");
					printf("%d\n",S);
					for(int j=mid;j<=r;j++) if(t[j].x) printf("%d ",t[j].x);
					printf("\n%d\n",t[i].x); fflush(stdout); scanf("%d",&k);
				}
				if(k) l=mid;
				else r=mid-1;
			}
			d[t[r].x]=t[i].x;
			sz-=t[r].s+1;
			t[r].x=t[r].s=0;
		}
	}
	printf("ANSWER\n"); fflush(stdout);
	for(int i=1;i<=n;i++) if(t[i].x) d[t[i].x]=1;
	for(int i=2;i<=n;i++) printf("%d %d\n",i,d[i]),fflush(stdout);
	fflush(stdout);
	return 0;
}
posted @ 2019-09-18 15:16  ZUTTER☮  阅读(137)  评论(0)    收藏  举报