首页 > 其他分享 >P7219 [JOISC2020] 星座 3 题解

P7219 [JOISC2020] 星座 3 题解

时间:2024-06-08 10:01:09浏览次数:14  
标签:星星 vector int 题解 JOISC2020 P7219 cost MAXN

会发现题目的坐标其实是平面直角坐标系。

我们按 \(y\) 坐标从小到大考虑所有的星星,假设当前考虑到了星星 \(i\)。我们先计算出之前所有能够影响到 \(i\) 的星星的代价和为 \(cost\)(可以用树状数组维护)。然后分类讨论。

若 \(c_i \le cost\),那么肯定直接将 \(i\) 直接涂黑,因为它更容易影响到后面的星星,并且删除它的代价更小。

若 \(cost < c_i\),我们可以用一种类似于反悔贪心的思路。先假设把 \(cost\) 删除,然后在树状数组中的 \([l,r]\) 区间加上 \(c_i-cost\)(\([l,r]\) 表示 \(i\) 能影响到的区间),这样之后考虑星星 \(j\) 的时候,如果需要删除星星 \(i\),那么 \(cost\) 中的一部分的代价也会加回去(但是不一定全部都加回去,因为 \(cost\) 中的一些星星也会影响 \(j\))。

然后就做完了,维护每颗星星的 \([l,r]\) 可以用并查集做。时间复杂度 \(O(n \log n)\)。

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair <int,int> pii;
const int MAXN = 2e5 + 10;
int n,a[MAXN],m,x[MAXN],y[MAXN],c[MAXN];
vector <pii> v[MAXN];
vector <int> f[MAXN];  
int tree[MAXN],ans = 0,fal[MAXN],far[MAXN];
inline int Lowbit(int x) {return x & -x;}
inline void Add(int x,int c) {for(;x <= n;x += Lowbit(x)) tree[x] += c;}
inline int Query(int x) {int r = 0;for(;x;x -= Lowbit(x)) r += tree[x];return r;}
inline int Findl(int x) {if(fal[x] == x) return x;return fal[x] = Findl(fal[x]);}
inline int Findr(int x) {if(far[x] == x) return x;return far[x] = Findr(far[x]);}
signed main() {
	cin >> n;
	for(int i = 1;i <= n;i++) cin >> a[i];
	for(int i = 0;i <= n + 1;i++) fal[i] = far[i] = i;
	for(int i = 1;i <= n;i++) f[a[i]].emplace_back(i); 
	cin >> m;
	for(int i = 1;i <= m;i++) 
		cin >> x[i] >> y[i] >> c[i],
		v[y[i]].emplace_back(make_pair(x[i],c[i]));
	for(int i = 1;i <= n;i++) {
		for(pii j : v[i]) {
			int cost = Query(j.first);
			if(j.second <= cost) ans += j.second;
			else ans += cost,
				Add(Findl(j.first) + 1,j.second - cost),
				Add(Findr(j.first),cost - j.second);
		}
		for(int j : f[i]) 
			fal[Findl(j)] = Findl(j - 1),
			far[Findr(j)] = Findr(j + 1);
	} cout << ans; return 0;
}

标签:星星,vector,int,题解,JOISC2020,P7219,cost,MAXN
From: https://www.cnblogs.com/Creeperl/p/18238333

相关文章

  • P10560 [ICPC2024 Xi'an I] The Last Cumulonimbus Cloud 题解
    好好玩的题。思路对于一个图上邻域问题,我们有一个很经典的做法:根号分治。考虑根号分治的本质是什么。我们把点分成两类,平衡每一种点的时间,也就是度数大的与度数小的点。所以对于这道题,我们有了更加好的做法。发现题目给的图的性质就是一个天然的划分方案。我们每次找到图中......
  • P10553 [ICPC2024 Xi'an I] Guess The Tree 题解
    挺有意思的题。思路考虑一个比较自然的做法。我们每次对于一棵树,我们将它的某一条链抽出来。这样,我们只需要知道这颗树的所有节点与链底的\(\text{lca}\),就可以知道它是属于这条链上哪一个节点的下面。然后就可以递归处理。由于交互库不是自适应的。我们可能可以想到随机......
  • P9000 [CEOI2022] Measures 题解
    思路简单题。考虑任意两点之间的限制。任意两点合法时必须要满足:\[\frac{d(j-i)-(a_j-a_i)}{2}\let(i\lej)\]所以答案即为:\[\max_{i\lej}\frac{d(j-i)-(a_j-a_i)}{2}\]使用线段树简单维护即可。时间复杂度:\(O((n+m)\log(n+m))\)。Code#include<bits/stdc++.h>using......
  • CF1192B Dynamic Diameter 题解
    思路静态\(\text{toptree}\)板子题。定义我们使用簇来表示树上的一个连通块。可以按照如下方式定义一个簇:一个簇可以表示为三元组\((u,v,E)\),其中\(u,v\)为树的节点,称为簇的界点,\(E\)为一个边的集合,表示该簇包含的边,路径\((u,v)\)称作簇路径。\(u,v\)分别为上界......
  • 无限之环 题解
    五星压行大师\(lyh\)表示:这是难得能让他的代码长度打破百行大关的题目(182行)。首先,根据科技与狠活,本题可以黑白染色。源点联向白格,黑格连向汇点。发现每个格子都可以连向四个方向,所以可以建立四个点,代表水管连到了上下左右四个方向。设四元组\((x,y,z,p)\)表示水管初始状态......
  • 开车旅行|倍增优化dp+双端列表/set|题解
    题面:题面链接这题的思路值得借鉴,也是我做的第一道倍增优化dp题目.比较好的是题目的意思较为清晰,所以不再赘述.解析:这里我们可以非常直接的想到暴力模拟,因为第一眼看上去前七个点的数据范围是支持我们进行一个简单的预处理得到对应人在对应位置的决策的.(排序O(n×sqrt(......
  • [ABC107D] Median of Medians 题解
    题目大意:一个长度为$M$的序列的中位数为这个序列从小到大排序后第$\lfloor\fracM2\rfloor+1$个数,将这个序列的所有子段的中位数放入一个序列中,求这个序列的中位数。设一个序列$a$的中位数为$x$,那么$a$中至少会有一半的数大于等于$x$,并且$x$是$a$中满足这个条件......
  • プログラミングコンテストチャレンジブック 题解
    题目大意:从$n$根木棒里选出六根拼成两个合法的三角形,使这两个三角形的周长和最大。考虑贪心,证明在后面。首先我们要知道一个三角形基本定理:较短两边长度之和大于最长边。那我们就根据这个定理先去寻找最大三角形的最长边。先排序,然后循环枚举,对于每个$a_i$,可以寻找到的最大......
  • [COCI2020-2021#2] Sjekira 题解
    题目大意:把一棵树完全分解,每次分解一条边的代价是这条边连接的两个连通块的最大点权之和,求最小代价。逆序模拟,既然题目要求将树完全分解,那我们就每次逆序连接当前权值最小的两个点,也就是贪心的思路。尝试将贪心的值写成一个表达式:$$\sum_{i=1}^na_i+\sum_{(u,v)\inE}\max(a......
  • [ABC036D] 塗り絵 题解
    题意题面讲挺清楚的就不简化了。思路树上求方案数,很明显是树上dp。设$dp_{i,0/1}$表示第$i$个点涂成白/黑色的方案数。当前结点如果为白色,那么它的子节点涂成什么颜色都没关系,根据分步乘法原理,将它子结点涂成白/黑色的方案数之和乘起来即可;当前结点如果为黑色,那么它的子......