首页 > 其他分享 >P9732 [CEOI2023] Trade

P9732 [CEOI2023] Trade

时间:2024-03-30 15:12:30浏览次数:14  
标签:int res update lsh Trade P9732 CEOI2023 maxn t1

洛谷传送门

LOJ 传送门

考虑第一问,设一个区间的价值 \(g(l, r)\) 为 \(f(l, r) - a_r + a_{l - 1}\),其中 \(a_i = \sum\limits_{j = 1}^i c_j\),\(f(l, r)\) 为 \([l, r]\) 中最大的 \(k\) 个 \(b_i\) 的和,设 \(p_i\) 为以 \(i\) 为右端点,区间价值最大的左端点,那么 \(p_i\) 满足决策单调性,也就是 \(p_i \le p_{i + 1}\)。

证明即证:

\[g(a, c) + g(b, d) \ge g(a, b) + g(c, d) \]

其中 \(a \le b \le c \le d\)。化简得:

\[f(a, c) + f(b, d) \ge f(a, b) + f(c, d) \]

即证:

\[f(a, b) + f(a + 1, b + 1) \ge f(a, b + 1) + f(a + 1, b) \]

考虑 \([a, b + 1]\) 相当于是 \([a + 1, b]\) 的加入两个单点 \(a\) 和 \(b\),它们能替换 \([a + 1, b]\) 中前 \(k\) 大的最小值和次小值,但是如果换成 \([a, b]\) 和 \([a + 1, b + 1]\),那么 \(a\) 和 \(b\) 只能分别替换 \([a + 1, b]\) 的最小值,所以 \([a, b], [a + 1, b + 1]\) 一定不劣。

所以第一问就可以直接基于这个利用分治算,\(g(l, r)\) 可以维护 \(l, r\) 的指针然后移动指针的同时用树状数组维护。

对于第二问,对于每个点求最大的 \(p_i\),然后把所有 \(g(p_i, i)\) 等于答案的 \([p_i, i]\) 从左往右扫,那么右端点为 \(i\),左端点在 \(l \sim p_i\) 之间(其中 \(l\) 为上一个 \(g(p_j, j)\) 等于答案的 \(p_j\))的区间会对第二问的答案有贡献。就相当于现在有一些形如 \((l, r, k)\) 的操作,意义是把 \(l \sim r\) 且 \(b_i \ge k\) 的 \(i\) 的答案设为 \(1\),那么直接对 \(k\) 扫描线,链表或并查集维护全部 \(b_i \ge k\) 且还没被覆盖过的点即可。

总时间复杂度 \(O(n \log^2 n)\)。

code
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<int, int> pii;

const int maxn = 250100;

ll n, m, a[maxn], b[maxn], lsh[maxn], tot, ans = -1e18;
vector<pii> S, vc[maxn];
vector<int> ap[maxn];

struct BIT {
	ll c[maxn];
	
	inline void init() {
		mems(c, 0);
	}
	
	inline void update(int x, ll d) {
		x = tot - x + 1;
		for (int i = x; i <= tot; i += (i & (-i))) {
			c[i] += d;
		}
	}
	
	inline ll query(int x) {
		x = tot - x + 1;
		ll res = 0;
		for (int i = x; i; i -= (i & (-i))) {
			res += c[i];
		}
		return res;
	}
	
	inline int kth(int k) {
		int s = 0, p = 0;
		for (int i = 18; ~i; --i) {
			if (p + (1 << i) <= tot && s + c[p + (1 << i)] < k) {
				s += c[p += (1 << i)];
			}
		}
		return tot - p;
	}
} t1, t2;

int l = 1, r;

inline ll calc(int L, int R) {
	while (l > L) {
		t1.update(b[--l], 1);
		t2.update(b[l], lsh[b[l]]);
	}
	while (r < R) {
		t1.update(b[++r], 1);
		t2.update(b[r], lsh[b[r]]);
	}
	while (l < L) {
		t1.update(b[l], -1);
		t2.update(b[l], -lsh[b[l]]);
		++l;
	}
	while (r > R) {
		t1.update(b[r], -1);
		t2.update(b[r], -lsh[b[r]]);
		--r;
	}
	int p = t1.kth(m);
	return t2.query(p + 1) + lsh[p] * (m - t1.query(p + 1)) - a[R] + a[L - 1];
}

void dfs(int l, int r, int pl, int pr) {
	if (l > r || pl > pr) {
		return;
	}
	int mid = (l + r) >> 1, p = -1;
	ll res = -1e18;
	for (int i = pl; i <= min(pr, mid - (int)m + 1); ++i) {
		ll val = calc(i, mid);
		if (val >= res) {
			res = val;
			p = i;
		}
	}
	if (res > ans) {
		ans = res;
		vector<pii>().swap(S);
		S.pb(p, mid);
	} else if (res == ans) {
		S.pb(p, mid);
	}
	dfs(l, mid - 1, pl, p);
	dfs(mid + 1, r, p, pr);
}

int fa[maxn];
bool f[maxn];

int find(int x) {
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}

void solve() {
	scanf("%lld%lld", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &a[i]);
		a[i] += a[i - 1];
	}
	for (int i = 1; i <= n; ++i) {
		scanf("%lld", &b[i]);
		lsh[++tot] = b[i];
	}
	sort(lsh + 1, lsh + tot + 1);
	tot = unique(lsh + 1, lsh + tot + 1) - lsh - 1;
	for (int i = 1; i <= n; ++i) {
		b[i] = lower_bound(lsh + 1, lsh + tot + 1, b[i]) - lsh;
		ap[b[i]].pb(i);
	}
	dfs(m, n, 1, n);
	sort(S.begin(), S.end());
	int i = 1;
	for (pii p : S) {
		while (1) {
			if (calc(i, p.scd) == ans) {
				vc[t1.kth(m)].pb(i, p.scd);
			}
			if (i == p.fst) {
				break;
			}
			++i;
		}
	}
	for (int i = 1; i <= n + 1; ++i) {
		fa[i] = i;
	}
	for (int i = 1; i <= tot; ++i) {
		for (pii p : vc[i]) {
			for (int j = find(p.fst); j <= p.scd; j = find(j + 1)) {
				f[j] = 1;
				fa[j] = j + 1;
			}
		}
		for (int j : ap[i]) {
			fa[j] = j + 1;
		}
	}
	printf("%lld\n", ans);
	for (int i = 1; i <= n; ++i) {
		putchar('0' + f[i]);
	}
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:int,res,update,lsh,Trade,P9732,CEOI2023,maxn,t1
From: https://www.cnblogs.com/zltzlt-blog/p/18105506

相关文章

  • 量化交易入门(十六)Backtrader、Zipline、PyAlgoTrade对比分析
    量化交易发展这么多年,有很多优秀的前辈为我们提供了各种开源的交易回测系统,我将对常用的Backtrader、Zipline、PyAlgoTrade这三个量化交易回测平台进行详细介绍,并进行对比分析。一、Backtrader概述:Backtrader是一个Python的事件驱动型回测框架,由社区驱动开发,功能全面且灵......
  • CF1618G Trader Problem 题解
    题目链接:CF或者洛谷本题挺有意思的,我们观察到\(\lek\)这个限制使得我们可以将原序列进行分组,把\(\lek\)的限制的元素放在一组中,那么根据题意,这组当中任意元素之间都是可以互相交换的,包括系统用品。那么假设一组中有\(x\)个自身的物品,\(y\)个系统物品,那么这\(x+y\)物......
  • trade calculator tcalc.py
    代码片#-*-coding:utf-8-*-importsysimportgetopt#fromqsutilimportgspaceasgsfromqsutilimportpklfname='c:\\GTJA\\RichEZ\\newVer\\cnt.pkl'#cn_dict=gs.pkl.pkl_load(fname)cn_dict=pkl.pkl_load(fname)classCBo......
  • CEOI2023D1T3(LOJ4019) Brought Down the Grading Server? (分治+欧拉回路)
    因为我们有\(S=2^k\),所以我们先考虑\(k=1\)即\(S=2\)的时候应该怎么做。发现如果我们对于每一个核心从\(t_1\)向\(t_2\)连一条无向边,如果我们把「不交换\(t_1,t_2\)」看成将这条边定向为\(t_1\tot_2\),否则如果「交换\(t_1,t_2\)」看成将这条边定向为\(t_2\tot_1......
  • 券商Ridder Trader牌照监管力度小,虚假宣传交易工具!
        毒舌君最近在网上看到一家券商RidderTrader,在要懂汇上了解到这家有澳大利亚牌照的券商,评分也只有3.78分,这是非常不推荐投资的,我们来查查这券商为何这么低分!一、牌照  1.澳大利亚牌照毒舌君在澳大利亚(ASIC)官网查到RIDDERTRADERPTYLTD的澳大利亚AR牌照确实受到监管。......
  • ProTradex(PRT)普瑞缇/提智能合约系统开发实现技术方案及源码解析
      区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。 区块链助推供应链上的数据更加透明,供应链上的企业可以准确的使用端到端的透明数据,区块链技术可以有效的对供应链上企业的交易进行数字化的处理,并且可以建立一个分散式的不可更改的所有......
  • 分享一套 MT4 crm MT4 MT5 CRM源码、web trade交易系统
    一套MT4MT5CRM源码,有跟单社区,同时支持MT4进行对接使用,支持代理返佣自由进行设置,可自动实时同步manager后台分组、交易品种和客户所有信息。包括带有内部实时内转功能,支持任何第三方支付、区块链和电子钱包。整套系统功能齐全。可节约公司大量租用成本和防止第三方公司泄露客户资......
  • WonderTrader 源码解析与改造-通用的dll加载器(未完待续)
    背景笔者学习WonderTrader的源码的一些心得体会,本文基于WonderTrader0.9.8,讲解其中的DLLHelper类先看它的应用1.wondertrader\src\TestTrader\main.cpp2.wondertrader\src\Includes\ITraderApi.h3.wondertrader\src\TraderCTP\TraderCTP.cpp......
  • Tradeoffs in scalable data routing for deduplication clusters 文献阅读
    前言本文提出了一个基于集群的数据去重存储系统GOLD1.高吞吐量2.可扩容3.高数据去重问题以何种粒度路由数据提出原因:块大小的减小,数据去重速率会增加,但是对于更大的块大小,由于流和文件间的局部性,吞吐量会增加方法:构建超级块如何将超级块分配给节点方法:使用称......
  • Backtrader - AttributeError: 'OptReturn' object has no attribute 'datas'
    1.0ErrorTraceback(mostrecentcalllast):File"D:/PycharmProjects/dbpower.backtrader.001/app/main_machine_learning.py",line191,in<module>img=cerebro.plot(style='line',plotdist=0.1,grid=True)File"D:\P......