返回顶部

Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2) D. Take a Guess (交互,位运算性质)

  • 题意:交互题,有一组长度位\(n\)的数,你最多可以询问\(2*n\)次,每次可以询问两个位置\(i\)\(j\),问他们的and或or值,求数组中第\(k\)大的数.
  • 题解: 对于两个数\(a\)\(b\),\(a\)&\(b\)\(a\)|\(b\),不难发现\(a+b\)=\(a\)&\(b\)+\(a\)|\(b\).因为\(a\)&\(b\)表示的是\(a\)\(b\)共同的一,而\(a\)|\(b\)是不进位的加法,于是现在我们要让没有进位的位置进位,而\(a\)&\(b\)刚好就是需要进位的位置,于是他们相加就能得到\(a+b\),那这样的话我们就可以得到\(a_1+a_2,a_1+a_3,...,a_1+a_n\)的值,在求出\(a_2+a_3\)的值,刚好\(2*n\)次,得到这个数组所有的值.
  • 代码:
#include <bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
#define me memset
#define rep(a,b,c) for(int a=b;a<=c;++a)
#define per(a,b,c) for(int a=b;a>=c;--a)
const int N = 1e6 + 10;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
using namespace std;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}

int n,k;
int a[N];
int sum[N];

int main() {
    scanf("%d %d",&n,&k);
    int x,y;
    printf("and 2 3\n");
    fflush(stdout);
    scanf("%d",&x);
    printf("or 2 3\n");
    fflush(stdout);
    scanf("%d",&y);
    sum[1]=x+y;
    for(int i=2;i<=n;++i){
        printf("and 1 %d\n",i);
        fflush(stdout);
        scanf("%d",&x);
        printf("or 1 %d\n",i);
        fflush(stdout);
        scanf("%d",&y);
        sum[i]=x+y;
    }
    a[1]=(sum[2]+sum[3]-sum[1])/2;
    for(int i=2;i<=n;++i) a[i]=sum[i]-a[1];
    sort(a+1,a+1+n);
    printf("finish %d\n",a[k]);
    fflush(stdout);

    return 0;
}
posted @ 2021-09-07 23:54  Rayotaku  阅读(36)  评论(0编辑  收藏  举报