codeforces1129E Legendary Tree

题面

题意

交互题,要求你通过询问确定一个有n个节点的树的边,每次询问输出两个集合S,T和点v,将会告诉你从S集合的某个点到T集合的某个点并经过点v的路径数。

做法

首先钦定点1为根节点,然后发现,询问({ x ∈ N ∗ x \isin N^* xN | 2 &lt; = x &lt; = n , x ̸ = i 2&lt;=x&lt;=n,x\not =i 2<=x<=n,x̸=i},{1}, i i i)可以得到i点的子树大小,然后根据字树大小从小到大排序之后就能发现,一个点的儿子全部在他左边。
可以用一个set维护还没确定父亲但已经确定儿子的点(一开始把所有叶子节点放进去),然后就要对一个点求在set中哪些是他的儿子。对此可以将set分成两半,用一次询问判断左边这半是否有点是他的儿子,如果有则左边递归下去,右边同样处理,可以发现这样确定某个点的父亲只要至多log次询问。

代码

#include<bits/stdc++.h>
#define P pair<int,int>
#define mp make_pair
#define fi first
#define se second
#define N 510
using namespace std;

int n,fa[N];
P num[N];
set<int>node;

inline void out()
{
    int i,j;
    puts("ANSWER");
    for(i=2;i<=n;i++) printf("%d %d\n",fa[i],i);
}

void dfs(int rt,set<int>::iterator now,int cnt)
{
    if(cnt==1)
    {
	fa[*now]=rt;
	node.erase(now);
	return;
    }
    int i,t,mid=(cnt>>1);
    set<int>::iterator tmp=now;
    printf("%d\n",mid);
    for(i=1;i<=mid;i++,now++)
    {
	printf("%d ",*now);
    }
    printf("\n1\n1\n%d\n",rt);fflush(stdout);
    scanf("%d",&t);
    if(t) dfs(rt,tmp,mid);
    
    printf("%d\n",cnt-mid);
    tmp=now;
    for(i=mid+1;i<=cnt;i++,now++)
    {
	printf("%d ",*now);
    }
    printf("\n1\n1\n%d\n",rt);fflush(stdout);
    scanf("%d",&t);
    if(t) dfs(rt,tmp,cnt-mid);
}

int main()
{
    int i,j;
    cin>>n;
    if(n==2)
    {
	fa[2]=1;
	out();
	return 0;
    }
    for(i=2;i<=n;i++)
    {
	num[i-1].se=i;
	printf("%d\n",n-2);
	for(j=2;j<=n;j++)
	{
	    if(i==j) continue;
	    printf("%d ",j);
	}
	printf("\n1\n1\n%d\n",i);
	fflush(stdout);
	scanf("%d",&num[i-1].fi);
    }
    sort(num+1,num+n);
    for(i=1;i<n;i++)
    {
	if(!num[i].fi)
	{
	    node.insert(num[i].se);
	    continue;
	}
	dfs(num[i].se,node.begin(),node.size());
	node.insert(num[i].se);
    }
    for(set<int>::iterator it=node.begin();it!=node.end();it++) fa[*it]=1;
    out();
}

### Codeforces 887E Problem Solution and Discussion The problem **887E - The Great Game** on Codeforces involves a strategic game between two players who take turns to perform operations under specific rules. To tackle this challenge effectively, understanding both dynamic programming (DP) techniques and bitwise manipulation is crucial. #### Dynamic Programming Approach One effective method to approach this problem utilizes DP with memoization. By defining `dp[i][j]` as the optimal result when starting from state `(i,j)` where `i` represents current position and `j` indicates some status flag related to previous moves: ```cpp #include <bits/stdc++.h> using namespace std; const int MAXN = ...; // Define based on constraints int dp[MAXN][2]; // Function to calculate minimum steps using top-down DP int minSteps(int pos, bool prevMoveType) { if (pos >= N) return 0; if (dp[pos][prevMoveType] != -1) return dp[pos][prevMoveType]; int res = INT_MAX; // Try all possible next positions and update 'res' for (...) { /* Logic here */ } dp[pos][prevMoveType] = res; return res; } ``` This code snippet outlines how one might structure a solution involving recursive calls combined with caching results through an array named `dp`. #### Bitwise Operations Insight Another critical aspect lies within efficiently handling large integers via bitwise operators instead of arithmetic ones whenever applicable. This optimization can significantly reduce computation time especially given tight limits often found in competitive coding challenges like those hosted by platforms such as Codeforces[^1]. For detailed discussions about similar problems or more insights into solving strategies specifically tailored towards contest preparation, visiting forums dedicated to algorithmic contests would be beneficial. Websites associated directly with Codeforces offer rich resources including editorials written after each round which provide comprehensive explanations alongside alternative approaches taken by successful contestants during live events. --related questions-- 1. What are common pitfalls encountered while implementing dynamic programming solutions? 2. How does bit manipulation improve performance in algorithms dealing with integer values? 3. Can you recommend any online communities focused on discussing competitive programming tactics? 4. Are there particular patterns that frequently appear across different levels of difficulty within Codeforces contests?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值