CF1305E Kuroni and the Score Distribution(構造)

Description

請你構造一個長爲 nn 的序列,使得滿足 ai+aj=aka_i + a_j = a_k 的三元組 (i,j,k)(i,j,k) 恰好有 mm 個。無解輸出 1-1

1n5000,1m1091 \leq n \leq 5000, 1 \leq m \leq 10^9

Solution

不難想到按 1,2,31,2,3 \dots 的方法填,那麼求一下以每個位置作爲 kk 的三元組個數,可以發現 a1+ak1=a2+ak2==ak1+a1=aka_1 + a_{k-1} = a_2+a_{k-2} = \dots = a_{k-1}+a_1 = a_k。因爲有重複的,所以貢獻爲 k12\left \lfloor\frac{k - 1}{2} \right\rfloor。一直填到 mik12m \leq \sum_i \left \lfloor\frac{k - 1}{2} \right\rfloor。如果填不到那麼無解。

可以發現讓最後一個數 +2+2 它的貢獻爲 k32=k121\left \lfloor\frac{k - 3}{2} \right\rfloor = \left \lfloor\frac{k - 1}{2} \right\rfloor - 1。所以給最後一個數加上 2×(m+ik12)2 \times (- m + \sum_i \left \lfloor\frac{k - 1}{2} \right\rfloor)。可能還沒有填完,因爲 nn 的規模小,所以從 10910^9 每次遞減最後一個數加一來填。時間複雜度爲 O(n)O(n)

Code

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5, INF = 0x3f3f3f3f;
inline int read() {
	int x = 0, f = 0; char ch = 0;
	while (!isdigit(ch)) f |= ch == '-', ch = getchar();
	while (isdigit(ch)) x = (x << 3) + (x << 1) + (ch ^ 48), ch = getchar();
	return f ? -x : x;
}
int ans[N];
int main() {
	int n = read(), m = read();
	int sum = 0, i;
	for (i = 1; i <= n && sum < m; i++) sum += (i - 1) / 2, ans[i] = i;
	if (sum < m) {
		puts("-1"); return 0;
	}
	ans[i - 1] += (sum - m) * 2; sum = 1e9;
	for (int j = n; j >= i; j--) ans[j] = sum, sum -= ans[i - 1] + 1;
	for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章