WA+T 求调
查看原帖
WA+T 求调
470769
DengStar楼主2024/9/9 20:50

AC + WA + TLE,提交记录
WA 就算了,不知道为什么会 T?时间复杂度应该没错,并且似乎没有可以出现死循环的地方。
思路和大多数题解相同,倍增+二分,代码有注释。

// F - Cake Division
#include<bits/stdc++.h>

using namespace std;

constexpr int INF = 0x3f3f3f3f;

int main()
{
	int n, K;
	cin >> n >> K;
	vector<int> a(n + 1), sum(2 * n + 1);
	for(int i = 1; i <= n; i++)
	{
		cin >> a[i];
		sum[i] = sum[i-1] + a[i];
	}
	for(int i = n + 1; i <= 2 * n; i++)
		sum[i] = sum[i-1] + a[i-n];
		
	vector<vector<int>> f(2 * n + 3);
	for(auto vec: f) vec.resize(__lg(K) + 1);
	
	auto check = [&](int x) -> int // 返回需要切开的切线的数量 
	{
		for(int i = 1, j = 1; i <= 2 * n; i++)
		{
			while(j < 2 * n && sum[j] - sum[i - 1] < x) j++;
			if(sum[j] - sum[i-1] >= x) f[i][0] = j + 1;
			else f[i][0] = 2 * n + 2; // 相当于INF 
		}
		f[2 * n + 2][0] = 2 * n + 2;
		
		int t = __lg(K);
		for(int k = 1; k <= t; k++)
			for(int i = 1; i <= 2 * n + 2; i++)
				f[i][k] = f[f[i][k-1]][k-1];
		
		int cnt = 0; // 能作为起点的点数 
		for(int i = 1; i <= n; i++) // 枚举每个点,判断其是否能成为起点
		{
			int en = i;
			for(int j = 0; (1 << j) <= K; j++)
				if(K & (1 << j)) en = f[en][j];
			if(en <= i + n) cnt++;
		}
		return cnt;
	};
	
	int l = 0, r = sum[n], ans = -1, cnt = -1;
	while(l <= r)
	{
		int mid = (l + r) >> 1, res = check(mid);
		if(res != 0) // 可行(至少有一个解) 
		{
			l = mid + 1;
			ans = mid, cnt = n - res;
		}
		else r = mid - 1;
	}
	
	cout << ans << ' ' << cnt << endl;
	
	return 0;
}
2024/9/9 20:50
加载中...