1 条题解

  • 0
    @ 2026-4-30 0:51:18

    看到最大值最小,一般是二分答案。

    处理环一般将原数组复制一次,这样可以处理跨 n1n \to 1

    考虑如何 check,要检查是否满足三块中最小的为 xx。可以计算 nexl\mathrm{nex}_l 表示满足

    i=lr1aix\sum_{i=l}^{r-1} a_i \ge x

    的最小 rr。然后枚举起点 p0p_0,计算三块蛋糕的终止位置:

    • p1=nexp0p_1=\mathrm{nex}_{p_0}
    • p2=nexp1p_2=\mathrm{nex}_{p_1}
    • p3=nexp2p_3=\mathrm{nex}_{p_2}

    并判断其是否都小于 p0+np_0+n

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    
    const int N = 100005;
    
    int n, a[2 * N], s, nex[2 * N];
    
    bool check(int x){
    	int cnt = 0;
    	for(int i = 1, j = 1; i <= 2 * n; ++ i){
    		for(; j <= 2 * n && cnt < x; cnt += a[j ++]);
    		nex[i] = j;
    		cnt -= a[i];
    	}
    	for(int i = 1; i <= n; ++ i){
    		int x = nex[i];
    		if(x > i + n) continue;
    		int y = nex[x];
    		if(y > i + n) continue;
    		int z = nex[y];
    		if(z > i + n) continue;
    		return 1;
    	}
    	return 0;
    }
    
    signed main(){
    	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    	
    	cin >> n;
    	for(int i = 1; i <= n; ++ i)
    		cin >> a[i], a[i + n] = a[i], s += a[i];
    	int l = 0, r = s, ans = -1;
    	while(l <= r){
    		int mid = (l + r) >> 1;
    		if(check(mid))
    			l = mid + 1, ans = mid;
    		else
    			r = mid - 1;
    	}
    	cout << ans;
    	
    	return 0;
    }
    
    • 1

    信息

    ID
    9008
    时间
    2000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者