锰锌刚学会决策单调性 求调
查看原帖
锰锌刚学会决策单调性 求调
169326
panxz2009楼主2024/7/21 16:07

死活过不了样例QWQ

#include <bits/stdc++.h>
#define int long long
#define ll long long
#define ld long double
using namespace std;
int read()
{
	int x = 0, f = 1;
	char ch = getchar();
	while(!isdigit(ch))
	{
		if(ch == '-')
			f = -1;
		ch = getchar();
	}
	while(isdigit(ch))
	{
		x = (x << 1) + (x << 3) + ch - '0';
		ch = getchar();
	}
	return x * f;
}
const int maxn = 1e5 + 10;
int n, L, P;
ll sum[maxn], len[maxn], p[maxn];
ld f[maxn];
string s, a[maxn];
struct que {
	int k, l, r;
}q[maxn];
int head, tail;
int ansq[maxn], atail;
ld qpow(ld a, int b)
{
	ld ans = 1;
	while(b)
	{
		if(b & 1) ans = ans * a;
		a = a * a;
		b >>= 1;
	}
	return ans;
}
ld val(int k, int i)
{
	ld tp = abs((ld)(sum[i] - sum[k] + i - k - 1 - L));
	return f[k] + qpow(tp, P);
}
int get_k(int i, int l, int r)
{
	int ans;
	while(l <= r)
	{
		int mid = (l + r) >> 1;
		if(q[mid].l <= i && q[mid].r >= i)
		{
			ans = mid;
			break;
		}
		if(q[mid].l <= i) l = mid + 1;
		else r = mid - 1;
	}
	return q[ans].k;
}
void Main()
{
	n = read(), L = read(), P = read();
	for(int i = 1; i <= n; i++)
	{
		cin >> s;
		len[i] = s.size();
		sum[i] = sum[i - 1] + len[i];
		a[i] = s;
	}
	head = 1, tail = 0;
	q[++tail] = {0, 1, n};
	for(int i = 1; i <= n; i++)
	{
		int k = get_k(i, head, tail);
		f[i] = val(k, i);
		p[i] = k;
//		printf("p[%d] = %d\nhead = %d\ntail = %d\n", i, k, head, tail);
		while(head <= tail && q[head].r <= i) head++;
		q[head].l = i + 1;
		int tmp = -1;
		while(head <= tail)
		{
			if(val(i, q[tail].l) <= val(q[tail].k, q[tail].l)) tmp = q[tail--].l;
			else
			{
				if(val(q[tail].k, q[tail].r) <= val(i, q[tail].r)) break;
				int l = q[tail].l, r = q[tail].r, ans = -1;
				while(l <= r)
				{
					int mid = (l + r) >> 1;
					if(val(i, mid) > val(q[tail].k, mid)) l = mid + 1;
					else r = mid - 1;
				}
				tmp = ans;
				q[tail].r = ans - 1;
				break;
			}
		}
//		cout << tmp << endl;
		if(tmp != -1)	
			q[++tail] = {i, tmp, n};
	}
	if(f[n] > 1e18)
	{
		puts("Too hard to arrange");
		puts("--------------------");
		return;
	}
	printf("%lld\n", (ll)f[n]);
	atail = 0;
	for(int i = n; i; i = p[i]) ansq[++atail] = i;
	ansq[++atail] = 0;
	for(int i = atail; i >= 2; i--)
	{
		for(int j = ansq[i] + 1; j < ansq[i - 1]; j++) cout << a[j] << " ";
		cout << a[ansq[i - 1]];
		puts("");
	}
	puts("--------------------");
}
signed main()
{
//	freopen("little_G.in", "r", stdin);
	int T = read();
	while(T--)
		Main();
	return 0;
}
2024/7/21 16:07
加载中...