CF1543D1D2(构造,位运算)

CF1543D1D2(构造,位运算)

题意

交互。

猜一个数 \(x\) ,最多 \(n\) 次询问,每次如果猜测失败,要将 \(x\) 变成 \(y\) 如果设此次猜测数字为 \(z\) ,则关系表示为 $ x \oplus _k z = y $ 。这里算符表示 \(k\) 进制下的不进位加法。

思路

一开始没仔细看题,看成 $ x \oplus y = z$ 写easy版本时候因为异或的自反性还给过了。于是hard版莫明其妙狂wa。。。


对这个式子,$ x \oplus _k z = y $ 我们先把未知量丢一边,有 $ x = y \ominus _k z$ 这里的 \(\ominus\)\(\oplus\) 的逆。

然后可以写出一个递推式子。

\[\left\{ \begin{aligned} x_0 = x \\ x_i = num_i \ominus _k x_{i-1} \end{aligned} \right. \]

这种时候如果找到一个通项式,也就写完了。

此时有两种想法。一种是硬递归展下去,一种是考虑构造一个 \(f(i) = num_i\) 使得 $x_i $ 只和 \(x_0\) 和每次询问数字 \(num_i\) 有关。

我们考虑 \(x_1 = num_1 \ominus x\)

\(x_2 = num_2 \ominus (num_1 \ominus x)\) 。考虑将前项元素 \(num_1\) 消去

\(num_2 = num_1 \ominus num_2\) 。代入上式发现 \(x_2 = x \ominus num_2\) 。满足需求

接下来对 \(x_3 = num_3 \ominus (x \ominus num_2)\) 。有类似构造 \(num_3 = num_3 \ominus num_2\)

从而我们知道,只要对每一项分奇偶讨论,就可以迭代寻找答案。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<stack>
#include<string>
#include<random>
#include<iomanip>
#define yes puts("yes");
#define inf 0x3f3f3f3f
#define ll long long
#define linf 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
// #define endl '\n'
#define int long long
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
using namespace std;
mt19937 mrand(random_device{}());
int rnd(int x) { return mrand() % x;}
typedef pair<int,int> PII;
const int MAXN =10 + 2e5 ,mod=1e9 + 7;
int get(int x,int y,int k) {
    int ans = 0,p = 1;
    while(x || y) {
        int t1 = x % k,t2 = y % k;
        x /= k, y /= k;
        ans += (t1 - t2 + k) % k * p;
        p *= k;
    }
    return ans;
}
void solve(){
    int n,k; cin >> n >> k;
    for(int i = 0;i < n;i ++) {
        int t;
        if(!i) {
            cout << i << endl;
            cin >> t;
            if(t) return;
        }else {
            if(i & 1) cout << get(i - 1,i,k) << endl;
            else cout << get(i,i - 1,k) << endl;
            cin >> t;
            if(t) return;
        }
    }
}
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

    int T;cin>>T;
    while(T--)
        solve();

    return 0;
}
posted @ 2022-07-03 17:37  Mxrurush  阅读(11)  评论(0编辑  收藏  举报