1 条题解

  • 1
    @ 2026-3-22 21:11:15

    二次答案二分,第一次求和,第二次求二元组的第一个数,check函数内部就是利用数学来写,具体看代码

    这里给一个答案二分模版的小tips,我们知道题目所需要的答案在 l-r 之间,如果 return 的表达式是 <= 那么最后的答案就是 l;如果是 < 那么最后的答案就是 r,lr 谁是答案就取决于等于答案的时候 check 函数是把答案赋给 l,还是赋给 r

    #include <bits/stdc++.h>
    using namespace std;
    using ll= long long;
    ll n,k;
    
    // 求出二元组和小于等于x的总对数
    ll count(ll x)
    {
        if (x<=n+1)
        return x*(x-1)/2;
        else return n*n-(2*n-x+1)*(2*n-x)/2;
    }
    
    // 用于判断和
    bool check1(ll x)
    {
        ll sum=count(x);
        return sum<k; 
    }
    
    // 用于判断二元组的第一个数
    bool check2(ll x,ll sum)
    {
        ll res=k-count(sum-1);
        ll one=max(1LL,sum-n);
        return x-one+1<=res;
    }
    
    int main()
    {
        ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        ll t;cin>>t;
        while(t--)
        {
            cin>>n>>k;
            ll l=1,r=n+n;
            while(l+1!=r)
            {
                ll mid=l+r>>1;
                if (check1(mid))
                l=mid;
                else r=mid;
            }
            ll sum=r;
            l=1,r=n+1;
            while(l+1!=r)
            {
                ll mid=l+r>>1;
                if (check2(mid,sum))
                l=mid;
                else r=mid;
            }
            cout<<l<<" "<<sum-l<<"\n";
        }
    }   
    
    • 1

    信息

    ID
    117
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    31
    已通过
    12
    上传者