1. 程式人生 > 實用技巧 >Codeforces Round #685 (Div. 2) E

Codeforces Round #685 (Div. 2) E

Codeforces Round #685 (Div. 2) E

大意

略...

思路

互動題,莫名好玩...

首先,我們需要確定一個位置作為基準,沒什麼特殊條件,於是假定選擇第一位作為基準,記為 \(a_1\)

因為題目保證了數字範圍,所以僅有兩種情況:

  1. 有相同的數
  2. 一個排列

先考慮一:

如果有兩個相同的數,那麼他們和 \(a_1\) 的異或值一定一樣,於是我們對值一樣的位置查詢一下 與 ,我們就得到了數列中的兩個值。

此時我們耗費了至多 \(n\) 次查詢。

那麼我們知道了一個值,知道了這個值和 \(a_1\) 的異或值,又知道了 \(a_1\) 和其餘數的異或值,可以很輕鬆的推出來原陣列了。

所以情況一至多耗費 \(n\) 次查詢。

情況二:

當我們在 \(n-1\) 次查詢後發現沒有相同的值,那麼,原陣列肯定是一個排列。

考慮如何獲得 \(a_1\) 的值。

因為是排列,肯定存在兩個數的與 \(a_1\) 的異或值分別為 \(2,1\) ,分別記為 \(a_i,a_j\)

顯然,\(a_i\)\(a_1\) 二進位制除了第二位都相同, \(a_j\)\(a_1\) 二進位制除了第一位都相同。

所以我們查詢 \(a_1,a_i\) 的 與 操作的值,就可以知道 \(a_1\) 在二進位制下第一位的值。

再查詢 \(a_1,a_j\) 的 與 操作的值,然後就能推出 \(a_1\)

於是就可以退出原陣列了

所以情況二嚴格耗費 \(n+1\) 次查詢

程式碼

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

#define ll long long
#define ull unsigned long long
#define cint const int&
#define Pi acos(-1)

const int mod = 998244353;
const int inf_int = 0x7fffffff;
const ll inf_ll = 0x7fffffffffffffff;
const double ept = 1e-9;

int n;
int sum[(1<<16)+1];
int ans[(1<<16)+1];

int query(cint key, cint x, cint y) {
    int tmp;
    if(key==1) cout << "AND " << x << ' ' << y << endl;
    else if(key==2) cout << "OR " << x << ' ' << y << endl;
    else if(key==3) cout << "XOR " << x << ' ' << y << endl;
    cout.flush();
    cin >> tmp;
    return tmp;
}

int main() {
    cin >> n;
    int a, id=0, lf=0;
    sum[0]=1;
    for(int i=2; i<=n; i++) {
        a = query(3, 1, i);
        ans[i] = a;
        if(!sum[a]) sum[a] = i;
        else id=i;
    }
    if(id) {
        int key = query(1, sum[ans[id]], id);
        ans[1] = ans[id] ^ key;
        for(int i=2; i<=n; i++)
            ans[i] ^= ans[1];
    } else {
        bool flag=0;
        int k1 = sum[1];
        int k2 = sum[2];
        int a1 = query(1, k1, 1);
        int a2 = query(1, k2, 1);
        int key = a1 + a2%2;
        for(int i=1; i<=n; i++) ans[i] ^= key;
    }
    cout << "! ";
    for(int i=1; i<=n; i++) cout << ans[i] << ' ';
    return 0;
}