首页 > 其他分享 >P8293 [省选联考 2022] 序列变换

P8293 [省选联考 2022] 序列变换

时间:2022-12-24 09:34:03浏览次数:75  
标签:sz P8293 省选 sum int 最小值 maxn 权值 联考

https://www.luogu.com.cn/problem/P8293

题解

题意转化:

将括号序列建成一棵树,操作1相当于把一个点和它的儿子都挂到同一深度的另一个点下面,操作2相当于表示同一深度的点不用管顺序,最后要求的就是把这棵树变成一条链的最小代价.

分类讨论:

  1. \(x = 0, y = 0\)

    答案为\(0\).

  2. \(x = 0, y = 1\)

    每一层的答案为\(sum\)(这一层点的权值和)减去留下的点的权值.

    策略就是留下权值最大的点,用\(multiset\)维护即可.

  3. \(x = 1, y = 1\)

    可以分两种情况讨论.

    如果留下的是权值最小的点,那么直接把其它点挂在权值最小的点的下面即可.答案为\(sum\)加上最小值乘\(sz - 2\).

    如果留下的不是权值最小的点,那么先把其它点挂到最小值的下面,最后再把最小值挂到留下的那个点的下面,答案还是\(sum\)加上最小值乘\(sz - 2\).

    策略还是每次留下最大值,还是可以用\(multiset\)维护.

  4. \(x = 1, y = 0\)
    假设当前留下的点的权值为\(val\),使用同样的策略,这一层的答案为\(val\)加上最小值乘\(sz - 2\).

    每一层的答案似乎不好单独计算,但是可以考虑总贡献.可以发现最后只有一个点的\(val\)不会被加,那个点会被放到最后一层.

    是不是所有点都能被放到最后一层?

    不是的,刚开始的一长段\(sz = 1\)的层是不能移动的.而对于\(sz > 2\)的层可以考虑把非最大值和非最小值留下来.

    最后的\(sz\)会形如\(1,1\cdots 1,2,2\cdots2,> 2,> 2,\cdots > 2,2,1\).

    也就是说,前面的一长段\(2\)最后只会下传出\(1\)个值,且贡献为这一段的所有的数的和减下传出的那个值,相当于最小值对它们没有贡献,因为\(sz - 2 = 0(sz = 2)\).

    所以,我们可以只考虑下传出的那个值和剩下的所有值.可以发现,下传值有两种影响,把它传到第\(n\)层,或让它贡献一段最小值.

    对于需要传到第\(n\)层的,它不可能产生最小的贡献,选最大的即可.

    对于需要贡献最小值的,选一个最小的值下传即可.

    综上,只需要选择一个最小值和一个最大值下传,再对答案取\(min\)即可,可以做到线性.

总结

考试的时候简单地认为选定一个点作为这一层的点之后,只需要把其它点移到它下面就行了,于是推出了一个错误的公式.

这是贪心策略的问题,是我思考不够全面的体现.

对于分类情况很少的题目,不要先想着得到一个通解,要分类讨论.

代码

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int inf = 1e9;
const int maxn = 800005;
int n, top1, top2, id[maxn];
int v[3], depth[maxn], cnt[maxn];
ll a[maxn], mn[maxn], mx[maxn];
int stk1[maxn], stk2[maxn], indeg[maxn];
char s[maxn];
vector<int> e[maxn];
void dfs(int u, int from) {
	depth[u] = depth[from] + 1;
	for(int i = 0; i < (int)e[u].size(); i++) {
		int v = e[u][i];
		dfs(v, u);
	}
}
vector<int> p[maxn];
multiset<int> st;
// v[1] = 0 v[2] = 1
void solve1() {
	ll ans = 0, sum = 0;
	for(int i = 1; i < n; i++) {
		for(int j : p[i]) {
			sum = sum + a[j];
			st.insert(a[j]);
		}
		auto it = st.end();
		it--;
		sum = sum - *it;
		ans = ans + sum;
		st.erase(it);
	}
	cout << ans << '\n';
}
// v[1] = 1 v[2] = 1
void solve2() {
	ll ans = 0, sum = 0;
	for(int i = 1; i < n; i++) {
		for(int j : p[i]) {
			sum = sum + a[j];
			st.insert(a[j]);
		}
		ans = ans + sum + (ll)(st.size() - 2) * (*st.begin());
		auto it = st.end();
		it--;
		sum = sum - *it;
		st.erase(it);
	}
	cout << ans << '\n';
}
// v[1] = 1 v[2] = 0
void solve3() {
	cnt[0] = 1;
	for(int i = 1; i <= n; i++)
		cnt[i] = cnt[i - 1] + (int)p[i].size() - 1;
	int l = 1, r = 1;
	while(l <= n && cnt[l] == 1)
		l++, r++;
	while(r <= n && cnt[r] == 2)
		r++;
	for(int i = 0; i <= n; i++) {
		mn[i] = inf;
		mx[i] = -inf;
	}
	ll sum = 0;
	for(int i = l; i < n; i++) {
		if(i != r) {
			mn[i] = mn[i - 1];
			mx[i] = mx[i - 1];
		}
		for(int j : p[i]) {
			mn[i] = min(mn[i], a[j]);
			mx[i] = max(mx[i], a[j]);
			sum = sum + a[j];
		}
	}
	ll ans1 = sum - mx[n - 1], ans2 = sum - max(mx[n - 1], mx[r - 1]);
	for(int i = r; i < n; i++) {
		ans1 = ans1 + min(mn[i], mn[r - 1]) * (cnt[i] - 2);
		ans2 = ans2 + mn[i] * (cnt[i] - 2);
	}
	cout << min(ans1, ans2) << '\n';
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n >> v[1] >> v[2];
	cin >> (s + 1);
	for(int i = 1; i <= n; i++)
		cin >> a[i];
	if(v[1] == 0 && v[2] == 0) {
		cout << "0\n";
		return 0;
	}
	int tot = 0;
	for(int i = 1; i <= n + n; i++) {
		if(s[i] == '(') {
			id[i] = ++tot;
			stk1[++top1] = i;
		}
		else {
			while(top2 && stk1[top1] < stk2[top2]) {
				e[id[stk1[top1]]].push_back(id[stk2[top2]]);
				indeg[id[stk2[top2]]]++;
				top2--;
			}
			stk2[++top2] = stk1[top1];
			top1--;
		}
	}
	for(int i = 1; i <= n; i++)
		if(!depth[i] && !indeg[i])
			dfs(i, 0);
	for(int i = 1; i <= n; i++)
		p[depth[i]].push_back(i);
	if(v[1] == 0 && v[2] == 1)
		solve1();
	else if(v[1] == 1 && v[2] == 1)
		solve2();
	else
		solve3();
	return 0;
}

标签:sz,P8293,省选,sum,int,最小值,maxn,权值,联考
From: https://www.cnblogs.com/yanchengzhi/p/17002032.html

相关文章

  • P8292 [省选联考 2022] 卡牌
    https://www.luogu.com.cn/problem/P8292题解先把小于等于\(\sqrt{2000}\)的质数打一个表,发现只有\(14\)个,其中第\(14\)个是\(43\).令前\(14\)个质数为小质数,其它的......
  • 省选11. 字符串
    P3426[POI2005]SZA-Template考虑dp,设\(f(i)\)表示前\(i\)字符所需要的最小印章。\(f(i)\)要么等于\(i\),要么等于\(f(nxt(i))\)。如果存在\(j\geqn-nxt(i)\),......
  • 省选知识点做题记录
    luogu[IOI2014]Wall砖墙题解可以转化为区间取\(min\)和区间取\(max\).规定一下下传标记的顺序推一下式子就行了.[NOIP2013提高组]华容道题解先想到了朴素的......
  • 省选07. 多项式
    P3338[ZJOI2014]力\[\begin{aligned}E_i&=\sum_{j=1}^{i-1}\frac{q_j}{(i-j)^2}-\sum_{j=i+1}^n\frac{q_j}{(i-j)^2}\end{aligned}\]设\(f(x)=q_x\),\(g(x)=x^2\),\(h(......
  • 省选08. 组合计数
    P4091[HEOI2016/TJOI2016]求和有一个重要的通项公式\[\begin{Bmatrix}n\\m\end{Bmatrix}=\sum_{i=0}^{m}\frac{i^n(-1)^{m-i}}{i!(m-i)!}\]\[ans=\sum_{i=0}^{n}\sum......
  • 省选09. 图论
    P2469[SDOI2010]星际竞速可以发现,一个点要么是起点,要么从其它点进入,且每个点最多只会进入一次,出去一次。因此,可以用流量限制每个点被访问一次,用费用计算代价,问题就转化......
  • 省选10. 动态规划
    P3736[HAOI2016]字符合并考虑区间dp+状压dp。设\(dp(l,r,s)\)表示\([l,r]\)合并成\(s\)的最大分数。如果\(r-l+1=len\),那么合并后的长度一定是\(len\bmod{......
  • 省选05. 线性代数
    P6772[NOI2020]美食家先假设没有美食节,容易得到一个矩阵优化的dp。加上美食节过后分成\(k\)段考虑,每段分别矩阵快速幂,时间复杂度为\(O((5n)^3k\logT)\)。这并不......
  • 省选06. 分治
    CF1442DSum设\(dp(i,j)\)表示前\(i\)个数组选\(j\)个元素的最大值。\[dp(i,j)=\max_{k=0}^jdp(i-1,k)+sum(i,k)\]因为数组内的元素单调不降,因此有一个结论,只有一......
  • 省选03. 树上问题
    P2664树上游戏首先,将贡献拆成每种颜色对每个点的贡献。考虑已经选择了一种颜色,将这些颜色的点和所对应边全部删去,就得到了很多连通块。假设其中一个连通块的大小为\(s......