gym 102392 C

题意
给你250个不同的数
每次操作可以查询单个位置的数,
或者查询k个位置的数两两的差的绝对值(返回乱序的k*(k-1)/2个数)
最多三十次操作还原这个数列

这简直太神妙了!
首先确定某个极值的下标,这个二分就行了。
然后我们看一下这是极大还是极小。两次询问即可。

神妙的东西来了!
我们怎么知道每个位置与当前极值到底差多少呢???
我们发现,n个数字都是不相同的!也就是说每个『差』只会出现一次。
那么我们枚举二进制位,如果这个『差』出现了,我们就给这个差的下标加上枚举的二进制下标
这样就能得到每个『差』对应的唯一位置。
还原即可

这个题完全没想到n个数字不同的用处。。。

我完蛋了啊

#include 
using namespace std;
int ask(int x){
    cout<<"2 "<>s;
        p=max(p,s);
    }
    return p;
}
vector ask(int id,vector &v,int sz){
    map mp;
    if(sz>=2) {
        cout << "2 " << sz;
        for (auto x:v)cout << ' ' << x;
        cout << endl;
        fflush(stdout);
        for (int i = 1, s; i <= sz * (sz - 1) / 2; i++) {
            cin >> s;
            mp[s]--;
        }
    }
    sz++;v.push_back(id);
    cout<<"2 "<>s;
        mp[s]++;
    }
    vector res;
    for(auto p:mp){
        if(p.second>0)
            res.push_back(p.first);
    }
    return res;
}
int n;
int ans[256];
int main(){
    ios::sync_with_stdio(false);
    cin>>n;
    if(n<=2){
        for(int i=1,x;i<=n;i++){
            cout<<"1 "<>x;
            ans[i]=x;
        }
        cout<<"3";
        for(int i=1;i<=n;i++)cout<<' '<>1;
        if(ask(mid)==mxd){
            r=mid-1;
        }else{
            l=mid+1;
        }
    }
    int mxid = l;//某个极值
    map mp;
    for(int i=0;i<8;i++){
        vector pos;
        for(int j=1;j<=n;j++)if(j&(1< res = ask(mxid,pos,pos.size());
        for(auto x:res){
            mp[x]+=(1<int{cout<<"1 "<>ind;return ind;};
    int v1 = que(mxid),v2 = que(oth);
    if(v1>v2){
        cout<<"3";
        for(int i=1;i<=n;i++){
            cout<<' '<

你可能感兴趣的:(gym 102392 C)