返回顶部

Codeforces Round #755 (Div. 2, based on Technocup 2022 Elimination Round 2) D. Guess the Permutation (交互,二分)

D. Guess the Permutation

  • 题意:交互题,一长度为\(n\)的排列,选择三个整数\(i,j,k\ (1\le i<j<k\le n,j-i>1)\),然后翻转区间\([i,j-1]\)\([j,k]\)内的元素。每次可以询问一个区间,告诉你区间逆序对的数量,让你在40次之内得出\(i,j,k\)

  • 题解:二分,每次询问\([l,mid]\),如果这个区间内逆序对数量不为\(0\),说明\(mid\)\([i,k]\)内,缩小右边界,否则缩小左边界,那么最终我们就能得到\(i\),然后在询问\([i,n]\)\([i+1,n]\)得到\(res1\)\(res2\),根据公式\(\frac{(len-1)*len}{2}=res1,\frac{(len-2)*(len-1)}{2}=res2\),两式相减得到:\(len=\frac{(res1-res2)*2+2}{2}\),那么也就求出了\(j\)的位置,同理得到\(k\)的位置.

  • 代码

    #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;}
     
    #define int long long
     
    signed main() {
        int _;
        scanf("%lld",&_);
        while(_--){
            int n;
            scanf("%lld",&n);
            int l=1,r=n;
            while(l<r){
                int mid=(l+r+1)>>1;
                printf("? %lld %lld\n",l,mid);
                fflush(stdout);
                int x;
                scanf("%lld",&x);
                if(!x) l=mid;
                else r=mid-1;
            }
            int i=l;
            int res1,res2;
            printf("? %lld %lld\n",i,n);
            fflush(stdout);
            scanf("%lld",&res1);
            printf("? %lld %lld\n",i+1,n);
            fflush(stdout);
            scanf("%lld",&res2);
            int len1=((res1-res2)*2+2)/2;
            int j=i+len1-1;
            j++;
            int res3,res4;
            printf("? %lld %lld\n",j,n);
            fflush(stdout);
            scanf("%lld",&res3);
            printf("? %lld %lld\n",j+1,n);
            fflush(stdout);
            scanf("%lld",&res4);
            int len2=((res3-res4)*2+2)/2;
            int k=j+len2-1;
            printf("! %lld %lld %lld\n",i,j,k);
            fflush(stdout);
        }
        return 0;
    }
    
posted @ 2021-11-16 10:34  Rayotaku  阅读(70)  评论(0编辑  收藏  举报