UOJ386UNR #3鸽子固定器ad-hoc,链表

Posted AThousandMoons

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UOJ386UNR #3鸽子固定器ad-hoc,链表相关的知识,希望对你有一定的参考价值。

给定 \\(n\\) 个二元组 \\((s_i,v_i)\\) 和正整数 \\(d_s,d_v\\),求选择 \\(m\\) 个二元组的 \\((\\sum v)^{d_v}-(\\max s-\\min s)^{d_s}\\) 的最大值。

\\(n\\le 2\\cdot 10^5\\)\\(m\\le 50\\)\\(d_s,d_v\\le 2\\)\\(1\\le s_i,v_i\\le 10^7\\)


显然按 \\(s\\) 排序之后就变成了选一个区间 \\([l,r]\\),贡献是这一段的前 \\(m\\) 大的 \\(v\\) 之和的 \\(d_v\\) 减去 \\((s_r-s_l)^{d_s}\\)

然后就被教育了:先枚举所有长度 \\(\\le m\\) 的区间,然后从小到大枚举第 \\(m\\)\\(v\\) 是哪个,用链表维护比 \\(\\ge\\) 当前 \\(v\\) 的二元组,只用看向左向右 \\(m\\),枚举 \\(m\\) 个区间计算答案。

时间复杂度 \\(O(nm)\\)

#include<bits/stdc++.h>
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
typedef long long LL;
const int N = 200003, M = 103;
template<typename T>
void rd(T &x){
	int ch = getchar(); x = 0;
	for(;ch < \'0\' || ch > \'9\';ch = getchar());
	for(;ch >= \'0\' && ch <= \'9\';ch = getchar()) x = x * 10 + ch - \'0\';
}
template<typename T>
bool chmax(T &a, const T &b){if(a < b) return a = b, 1; return 0;}
int n, m, k, ds, dv, id[N], lst[N], nxt[N], b[M];
pii a[N];
LL ans, sum[M];
LL valv(LL v){return dv == 1 ? v : v * v;}
LL vals(LL s){return ds == 1 ? s : s * s;}
int main(){
	rd(n); rd(m); rd(ds); rd(dv);
	for(int i = 1;i <= n;++ i){
		rd(a[i].fi); rd(a[i].se);
	}
	sort(a+1, a+n+1);
	for(int i = 1;i <= n;++ i){
		LL s = a[i].se;
		for(int j = i;j < i+m && j <= n;s += a[++j].se)
			chmax(ans, valv(s) - vals(a[j].fi-a[i].fi));
	}
	for(int i = 1;i <= n;++ i){
		lst[i] = i-1; nxt[i] = i+1; id[i] = i;
	}
	sort(id+1, id+n+1, [&](int x, int y){return a[x].se==a[y].se ? x<y : a[x].se<a[y].se;});
	for(int _ = 1;_ <= n-m+1;++ _){
		k = 0; int i = id[_];
		for(int j = 1, p = lst[i];j < m && p;++ j, p = lst[p]) b[++k] = p;
		reverse(b+1, b+k+1); b[++k] = i;
		for(int j = 1, p = nxt[i];j < m && p <= n;++ j, p = nxt[p]) b[++k] = p;
		for(int j = 1;j <= k;++ j) sum[j] = sum[j-1] + a[b[j]].se;
		for(int j = m;j <= k;++ j)
			chmax(ans, valv(sum[j]-sum[j-m]) - vals(a[b[j]].fi-a[b[j-m+1]].fi));
		lst[nxt[i]] = lst[i]; nxt[lst[i]] = nxt[i];
	}
	printf("%lld\\n", ans);
}

以上是关于UOJ386UNR #3鸽子固定器ad-hoc,链表的主要内容,如果未能解决你的问题,请参考以下文章

uoj#386. UNR #3鸽子固定器(乱搞)

UOJ386UNR #3鸽子固定器 链表

uoj308 UNR #2UOJ拯救计划

UOJ#308UNR#2UOJ拯救计划

UOJ #390. UNR #3百鸽笼

[UOJ388]UNR #3配对树