首页 > 其他分享 >QOJ 8726 [APIO2024] 魔术表演 题解

QOJ 8726 [APIO2024] 魔术表演 题解

时间:2024-10-03 21:26:02浏览次数:1  
标签:std 题解 Catherine Alice long second APIO2024 Bob QOJ

Description

Alice 和 Bob 是著名的魔术师。Catherine 是一位富豪,她非常喜欢观看 Alice 和 Bob 的魔术。某一天,Catherine 决定向 Alice 和 Bob 发出挑战:只要他们能成功表演如下的魔术,Catherine 就将向他们提供巨额奖金!这个魔术的表演过程如下:

  • 步骤 \(1\):Bob 进⼊⼀个密室中,在魔术的全程中,他只能与 Catherine 交流。接下来,Alice 告诉 Catherine ⼀个在 \(2\) 到 \(5000\) 之间的整数 \(n\)。
  • 步骤 \(2\):Catherine 告诉 Alice ⼀个在 \(1\) 到 \(10^{18}\) 之间的整数 \(X\)。
  • 步骤 \(3\):Alice 生成⼀个具有 \(n\) 个节点的树,并告诉 Catherine。
  • 步骤 \(4\):Catherine 删除树中的⼀些边(至多 \(\left\lfloor\dfrac{n-2}{2}\right\rfloor\) 条),并将剩余的边告诉 Bob。
  • 步骤 \(5\):Bob 根据 Catherine 给出的信息,猜出 Catherine 告诉 Alice 的数是多少。

然⽽,Alice 和 Bob 被这个魔术难倒了,于是他们不得不寻求你的帮助。请你写一段程序,实现 Alice 和 Bob 的策略,以帮助他们赢得 Catherine 的挑战。

Solution

注意到利用树的形态+编号很难刻画这个数,因为删掉一半的边后整棵树会变得非常不一样。

考虑利用数论去确定这个数。具体的,对于一个数 \(v(2\leq v\leq n)\),让 \(X\bmod (v-1)+1\) 和 \(v\) 连边,这样交互库删掉一半的边后剩下的边也能通过 CRT 非常宽松地得到 \(X\)。

Code

Alice
#include "Alice.h"
#include <bits/stdc++.h>

std::vector<std::pair<int, int>> Alice() {
  int n = 5000;
  long long x = setN(n);
  std::vector<std::pair<int, int>> ed;
  for (int i = 2; i <= n; ++i) ed.emplace_back(x % (i - 1) + 1, i);
  return ed;  
}
Bob
#include "Bob.h"
#include <bits/stdc++.h>

using i128 = __int128_t;
using pii = std::pair<i128, i128>;

pii merge(pii a, pii b) {
  if (a.second > b.second) std::swap(a, b);
  i128 lcm = a.second / std::__gcd(a.second, b.second) * b.second;
  for (int i = 0; i < a.second; ++i)
    if ((b.first + b.second * i) % a.second == a.first)
      return {b.first + b.second * i, lcm};
}

long long Bob(std::vector<std::pair<int, int>> V) {
  pii now = {0, 1};
  for (auto [u, v] : V) {
    if (u > v) std::swap(u, v);
    now = merge(now, {u - 1, v - 1});
    if (now.second > (i128)1000000000000000000) return (long long)now.first;
  }
}

标签:std,题解,Catherine,Alice,long,second,APIO2024,Bob,QOJ
From: https://www.cnblogs.com/Scarab/p/18446012

相关文章

  • 题解:洛谷P2339 [USACO04OPEN] Turning in Homework G
    题目链接:洛谷P2339[USACO04OPEN]TurninginHomeworkG首先我们考虑如何处理到达给定时间后才能交作业这一限制。其实在生活中,我们一般只会考虑什么时候交作业截止(除了某些卷王),这样我们只用考虑如何在最大结束时间之前交作业,而不是在所有作业都没开始交之前考虑如何转悠(前者明......
  • 题解:CF2009G1 Yunli's Subarray Queries (easy version)
    题目要求\(a_i=a_{i-1}+1\),设\(b_i=a_i-i\),如果\(b_i=b_j\),那么\(i\)和\(j\)就在正确的相对位置上。这应该很好理解吧,\(a\)是一个公差为\(1\)的等差数列,下标也是一个公差为\(1\)的等差数列,对应位置相减就相等了。我们在输入\(a_i\)的时候减去\(i\),然后用滑动窗口......
  • [题解] [SDOI2011] 消防
    [题解][SDOI2011]消防tag:图论、树、树的直径题目链接(洛谷):https://www.luogu.com.cn/problem/P2491题目描述给定一棵\(n\)个节点的树,第\(i\)条边有边权\(z_i\)。要求找到树上一条长度不大于\(s\)的简单路径,使得不在路径上的点到该路径的最大距离最小。数据范围:\(1......
  • 算法基础课——基础算法题解
    排序算法(分治)快速排序:题面:给定你一个长度为\(n\)的整数数列。请你使用快速排序对这个数列按照从小到大进行排序。并将排好序的数列按顺序输出。输入格式输入共两行,第一行包含整数\(n\)。第二行包含\(n\)个整数(所有整数均在\(1\sim10^9\)范围内),表示整个数列。输......
  • 题解9.29-10.3
    1.MakeitAlternating如果它已经是交替的序列我们就不用管了,最终的目的是把序列变成交替的序列,那么我们可以把连续相同的数全部取出来只留下一个,可以分成几段相同的数,最后的结果就是把这些相同的数全部只保留一个,用排列组合C(m,1);第一个结果很简单,把重复的数加一下即可,后面的答......
  • CF1051F题解
    传送门:https://codeforces.com/problemset/problem/1051/F注意到\(m-n\le20\),求一个连通图中任意两点间最短路,我们不难想到将问题转换到树上。先求出树的任意一颗生成树,此时倍增或者树刨能轻松算出仅含树边的最小路径。而对于非树边,从边的角度显然很难做到,我们不妨从点的角度思......
  • 题解:CF724E Goods transportation
    可以在cnblog中阅读。题意有\(n\)座城市,第\(i\)座城市生产了\(p_i\)件货物,最多可以出售\(s_i\)件货物,编号小的城市可以向编号大的城市运输至多\(c\)件货物,问最多能出售多少货物。\(n\le10^4\)。分析乍一看是一个网络流问题,可以这样建图,令\(S\)为源点\(T\)......
  • ABC221G Jumping Sequences 题解
    JumpingSequences把移动的上下左右改成左上、左下、右上、右下(坐标轴旋转\(45\)°)。则最终目的地是\((A+B,A-B)\)。(以前移动的方式是\((\pmd_i,0),(0,\pmd_i)\)。现在每次移动的方式是\((\pmd_i,\pmd_i)\))则\(x,y\)两维可以分开考虑。目标:从\(d_1\simd_n\)中选......
  • Codeforces Round 976 (Div. 2) 题解
    CodeforcesRound976(Div.2)题解2020B一个常见的想法:开关灯=异或,虽然在这道题里没啥用注意到,第i盏灯的按钮被按的次数就是i的除它本身以外的因子个数而完全平方数的因子数为奇数,其他数的因子数为偶数点击查看更多信息#include<bits/stdc++.h>usingnamespacestd;voi......
  • 题解:CF1976D Invertible Bracket Sequences
    可以在cnblog中阅读。题意给一个合法括号序列,问有多少区间\([l,r]\),使得将区间内的每个括号翻转后,括号序列仍合法。分析十分套路地,我们将(看成\(+1\),将)看成\(-1\),则一个括号序列合法的充要条件是转换后的序列满足:前缀和任意位置非负;最后一项为\(0\)。考虑翻转......