CF833B The Bakery

题意

将一个长度为\(n\)的序列分为\(k\)
使得总价值最大
一段区间的价值表示为区间内不同数字的个数
\(n<=35000,k<=50\)

Sol

首先可以设状态\(f[i][j]\)
表示前\(i\)个数字分成\(j\)段的最大价值
\(f[i][j] = max\){\(f[l][j - 1] + Query(l + 1, i)\)}\((0 <= l <= i - 1)\)
\(Query(l + 1, i)\)表示\(l+1\)\(i\)的不同数的个数

然后
你会发现
\(i\)这个位置上的数上次的位置为\(lst\)
则枚举到这个数字后,\(lst\)\(i-1\)这些\(f\)都要加\(1\)
那么就可以枚举\(k\)
然后每次重构线段树,把上一次分的\(f\)放进去
查询+区间加法

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(4e4 + 5);

IL int Input(){
	RG int x = 0, z = 1; RG char c = getchar();
	for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
	for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
	return x * z;
}

int n, k, a[_], mx[_ << 2], tag[_ << 2], f[_], lst[_], id[_];

IL void Build(RG int x, RG int l, RG int r){
	tag[x] = 0;
	if(l == r){
		mx[x] = f[l];
		return;
	}
	RG int mid = (l + r) >> 1;
	Build(x << 1, l, mid), Build(x << 1 | 1, mid + 1, r);
	mx[x] = max(mx[x << 1], mx[x << 1 | 1]);
}

IL void Modify(RG int x, RG int l, RG int r, RG int L, RG int R){
	if(L <= l && R >= r){
		++mx[x], ++tag[x];
		return;
	}
	RG int mid = (l + r) >> 1;
	if(L <= mid) Modify(x << 1, l, mid, L, R);
	if(R > mid) Modify(x << 1 | 1, mid + 1, r, L, R);
	mx[x] = max(mx[x << 1], mx[x << 1 | 1]) + tag[x];
}

IL int Query(RG int x, RG int l, RG int r, RG int L, RG int R){
	if(L <= l && R >= r) return mx[x];
	RG int mid = (l + r) >> 1, ans = 0;
	if(L <= mid) ans = Query(x << 1, l, mid, L, R);
	if(R > mid) ans = max(ans, Query(x << 1 | 1, mid + 1, r, L, R));
	return ans + tag[x];
}

int main(RG int argc, RG char *argv[]){
	n = Input(), k = Input();
	for(RG int i = 1; i <= n; ++i)
		a[i] = Input(), lst[i] = id[a[i]], id[a[i]] = i;
	for(RG int i = 1; i <= k; ++i){
		Build(1, 0, n), Fill(f, 0);
		for(RG int j = i; j <= n; ++j){
			Modify(1, 0, n, lst[j], j - 1);
			f[j] = Query(1, 0, n, 0, j - 1);
		}
	}
	printf("%d\n", f[n]);
	return 0;
}

posted @ 2018-03-17 14:43  Cyhlnj  阅读(655)  评论(0编辑  收藏  举报