Educational Codeforces Round 180 (Rated for Div. 2) C. Coloring Game

C -- Coloring Game

思路:不难看出,当 Alice 选完三个数 a b c(其中 a ≤ b ≤ c)后,Bob 能选的只有两种情况:

  1. 选择 c,这样只用比较 a+b 和 c 的大小关系,其中 a+b 一定要大于c;
  2. 选择数组最大值 a[n],这样只用比较 a+b+c 和 a[n] 的大小关系,且前者要更大。
    所以,排序后枚举外层 a_id 和内层 b_id:
  • 对于情况1:因为 a+b 的和一开始较小,后续逐渐变大,所以最大能选择的 c_id 一开始会较小,然后会随着 b_id 的变大而变大,该情况的"最大满足当前条件的 c_id"记为 k;
  • 对于情况2:因为 a+b 的和一开始较小,需要较大的 c 才能使得 a+b+c > a[n],因此满足条件的最小 c_id 一开始会较大,后续随着 a+b 的增大而变小,该情况的"最小满足当前条件的 c_id"记为 l。

那么,对于每对 (a_id, b_id),可选的 c_id 数量即为 [l, k] 区间长度。利用 k、l 单调移动的特点,可用双指针在 O(n²) 内完成。
view code

cpp 复制代码
#include<bits/stdc++.h>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '\n'
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0; rep(i,1,n+1) res=(res+k)%i; return (res+s)%n;}
inline ll read(){ ll f=1,x=0; char ch=getchar(); while(ch>'9'||ch<'0'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); } return x*f; }
int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};

ll a[maxn];

void sol() {
    ll n = read();
    rep(i,1,n) a[i] = read();
    sort(a+1,a+1+n);
    ll ans = 0;
    rep(i,1,n) {
        ll k = i+2, l = n;
        rep(j,i+1,n-1) {
            while(k <= n && a[i] + a[j] > a[k]) k++;
            while(l > j && a[i] + a[j] + a[l] > a[n]) l--;
            ll k1 = min(n, k-1), l1 = max(l+1, j+1);
            if(k1 >= l1) ans += (k1 - l1 + 1);
        }
    }
    cout << ans << endl;
}

int main() {
    int kase;
    cin >> kase;
    while(kase--) sol();
    return 0;
}
相关推荐
Timmylyx05189 天前
CF 新年赛 Goodbye 2025 题解
算法·codeforces·比赛日记
Timmylyx05189 天前
2025年最后一搏—— Educational Codeforces Round 186 (Rated for Div. 2) 题解
算法·codeforces·比赛日记
ddmdd1 个月前
codeforces Round 1070(Div. 2)
codeforces
defaulter3 个月前
Codeforces Round 1049 (Div. 2)C. Ultimate Value
算法·codeforces
图灵信徒4 个月前
ICPC Central Russia Regional Contest, 2024
c++·python·codeforces·算法竞赛
超闻逸事5 个月前
题解:CF2129C Interactive RBS
c++·算法·codeforces
ReineRabbit5 个月前
重生之 CF2126G2. Big Wins! (hard version)
线段树·codeforces·中位数
Savior`L6 个月前
Educational Codeforces Round 181 (Rated for Div. 2)
数据结构·c++·算法·codeforces
Closet1237 个月前
Codeforces 2025/6/11 日志
c++·算法·codeforces