HDU 5573-Binary Tree【思维+二进制】

野性酷女 2023-08-17 17:28 216阅读 0赞

题意:给你一个满二叉树,对于每个结点u,左儿子结点时2u,右儿子是2u+1,给你一个n和k,问你选一条k个节点的路径,每个点你可以选择加上或者减去这个结点的编号值,要求最终答案是n。

思路:我们考虑选择最左边的那条链,对于n是任意偶数而言,不难发现都可以构成。而对于n是奇数而言,我们在选择第k个时选择右儿子,最末尾的1就可以消掉转换成了偶数的情况。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. #define ls rt << 1
  5. #define rs rt << 1|1
  6. #define mid ((l + r) >> 1)
  7. #define lson l, mid, ls
  8. #define rson mid + 1, r, rs
  9. const int maxn = 100;
  10. const int mod = 1e9 + 7;
  11. bool vis[maxn];
  12. int main()
  13. {
  14. int t, t1 = 1;
  15. scanf("%d", &t);
  16. while(t--)
  17. {
  18. printf("Case #%d:\n", t1++);
  19. memset(vis, false, sizeof(vis));
  20. ll n;
  21. int k;
  22. scanf("%lld%d", &n, &k);
  23. ll sum = 0;
  24. for(int i = 0; i < k; ++i)
  25. {
  26. sum += (1ll << i);
  27. }
  28. if(n % 2 == 0)
  29. sum++;
  30. ll tmp = (sum - n) / 2;
  31. for(int i = 60; i >= 0; --i)
  32. {
  33. if(tmp & (1ll << i))
  34. vis[i] = true;
  35. }
  36. for(int i = 0; i < k - 1; ++i)
  37. {
  38. printf("%lld ", (1ll << i));
  39. if(vis[i]) printf("-\n");
  40. else printf("+\n");
  41. }
  42. tmp = (1ll << (k - 1));
  43. if(n % 2 == 0) tmp++;
  44. printf("%lld +\n", tmp);
  45. }
  46. return 0;
  47. }

发表评论

表情:
评论列表 (有 0 条评论,216人围观)

还没有评论,来说两句吧...

相关阅读