P17761 「奶龙OI」Round 3 - 红石大佬

· · 题解

这题一眼看上去,只能 \Theta(1) 计算:数据范围太大了!

那么只能推式子了。我们先给出答案:

当 2k\not=n 时,ans=\min(3k,2n-k);

反之,ans=3k-1 或 2n-k-1。

::::info[证明]

1. 两个关键上界

设 S 为种子集合,|S|=k;W 为长出西瓜的空格集合,|W|=ans。

综上,理论最大值恒满足:

ans \le \min(3k, 2n-k)

2. 分类讨论构造

情形一:2k \neq n

小结:当 2k \neq n 时,两种子情形均能取到上界,故 ans = \min(3k, 2n-k)。

情形二:2k = n(特殊情况)

这是本题唯一的"陷阱"。此时 3k = 2n-k = 1.5n,理论上界重合。但实际无法同时满足"全覆盖"和"无重叠"。

3. 最终公式

ans = \begin{cases} \min(3k, 2n-k) & \text{if } 2k \neq n \\ 3k - 1 & \text{if } 2k = n \end{cases}

:::info[声明] 本部分使用千问 AI 进行优化。 ::: ::::

放上代码:

:::success[AC Code]

//��ʾ���ˣ�ʮ��OIһ���գ�����long long������
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define AC 0
using ll=long long;
using pll=pair<int,int>;
template<typename T>
inline void readinVector(vector<T>& vec,int l,int r){
    for(int i=l;i<=r;i++)cin>>vec[i];
}
template<typename T>
class matvec{
public:
    vector<vector<T> >mat;
    matvec(){}
    matvec(int n){
        mat.resize(n+1);
    }
    void rs(int n){
        mat.resize(n+1);
    }
    matvec(int n,int m){
        mat.resize(n+1,vector<T>(m+1));
    }
    matvec(int n,int m,T v){
        mat.resize(n+1,vector<T>(m+1,v));
    }
    vector<T>& operator[](int i){
        return mat[i];
    }
    void p_b(const vector<T>&vec){
         mat.push_back(vec);
    }
};
int T=1;
void solve(){
    int n,a;
    cin>>n>>a;
    if(n==a*2){
        cout<<3*a-1<<endl;
        return;
    }
    cout<<min(3*a,2*n-a)<<endl;
}
signed main(){
//  freopen("xxx.in","r",stdin);
//  freopen("xxx.out","w",stdout);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin>>T;
    while(T--)solve();
    return AC;
    //AK IOI!;
}

:::