首页 > 其他分享 >BC2402C. 多重集(set)

BC2402C. 多重集(set)

时间:2024-10-15 20:13:14浏览次数:7  
标签:ch int max top 多重集 BC2402C 最小值 set define

BC2402C. 多重集(set)

题意

给你两个集合 \(A,B\),开始时集合为空。有 \(n\) 次操作,每次往其中一个集合插入或者删除一个数对 \((a,b)\),保证删除的数对存在。每次操作后输出 \(\min_{x,y} \{ \max(a_x+a_y,b_x+b_y),(a_x,b_x)\in A,(a_y,b_y) \in B \}\)。

思路

一个显然的优化是按照 \(a_x+a_y,b_x+b_y\) 的大小关系分类讨论,以此去除讨厌的 \(\max\)。

当 \(a_x+a_y \ge b_x+b_y\) 时,有 \(a_x-b_x \ge -a_y + b_y\)。因此我们可以对于每一个 \(x\),对于满足 \(a_x-b_x \ge -a_y + b_y\) 的 \(y\),取 \(\max\) 一定会取到 \(a_x+a+y\),因此对这些 \(y\) 求 \(a\) 的最小值。对于 \(a_x-b_x < -a_y + b_y\) 的 \(y\) 同理,求 \(b\) 的最小值。

只考虑插入操作,可以将操作离线,以 \(a_i-b_i\) 对离散化后的操作排序,相当于前缀或者后缀求最小值,以及动态插入,用线段树可以维护。

然后愚蠢的我以为求最小值不支持删除操作。大概是被莫队搞晕了。线段树本来就是支持单点甚至区间修改维护最大值和最小值的。

因此删除操作就单点删除,然后上传更新最小值即可。

时间复杂度是 \(O(n \log n)\)。主要难点在于想到对 \(\max\) 进行分类讨论(需要做题经验显然我好不容易有了然后脑抽以及不要脑抽

一种比较优美的写法是,首先线段树节点肯定要存 \(a,b\) 最小值,把两个集合的信息一个集合以 \(a_i-b_i\) 排名为下标,另一个以 \(-a_i+b_i\) 排名为下标,存在一棵树里,在线段树里维护答案。

code

感觉减少常数需要精细思考,但是代码还是很好写的。

#include<bits/stdc++.h>
// #define LOCAL
#define sf scanf
#define pf printf
#define rep(x,y,z) for(int x=y;x<=z;x++) 
#define per(x,y,z) for(int x=y;x>=z;x++)
using namespace std;
typedef long long ll;
constexpr int N=1e6+7;
#define isdigit(x) (x>='0'&&x<='9')
template <typename T>
void read(T &x) {
	x=0;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) ;
	for(;isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
}
template <typename T>
void write(T x,char ch) {
	static int st[20];
	int top=0;
	do {
		st[top++]=x%10;
		x/=10;
	}while(x);
	while(top) putchar(st[--top]+'0');
	putchar(ch);
}
int q;
int cnt;
typedef unsigned int uint;
constexpr uint inf=0x7f7f7f7f;
struct pii {
	uint a,b;
	bool operator < (const pii x) const { return a!=x.a?a<x.a:b<x.b; }
};
struct node {
	int d;
	pii x;
	bool operator < (const node y) const { 
		int c1=d?x.b-x.a:x.a-x.b,c2=y.d?y.x.b-y.x.a:y.x.a-y.x.b;
		return c1!=c2 ? c1<c2 : (d!=y.d?d<y.d:x<y.x) ;
	}
}t[N];
struct que{
	int op,d;
	pii x;
}qu[N];
int op,d,a,b;
struct tree {
	pii mn[N<<2][2]; uint tr[N<<2];
	tree() { memset(mn,0x7f,sizeof(mn)); memset(tr,0x7f,sizeof(tr)); }
	pii _min(pii x,pii y) { return {min(x.a,y.a),min(x.b,y.b)}; }
	void pushup(int u) {
		mn[u][0]=_min(mn[u<<1][0],mn[u<<1|1][0]); mn[u][1]=_min(mn[u<<1][1],mn[u<<1|1][1]);
		tr[u]=min(min(tr[u<<1],tr[u<<1|1]),min(mn[u<<1][1].a+mn[u<<1|1][0].a,mn[u<<1][0].b+mn[u<<1|1][1].b));
	}
	void insert(int u,int l,int r,int x,int del) {
		if(l==r) {
			if(del) memset(mn[u],0x7f,sizeof(mn[u])), tr[u]=inf;
			else mn[u][t[x].d]=t[x].x;
			return;
		}
		int mid=(l+r)>>1;
		if(x<=mid) insert(u<<1,l,mid,x,del);
		else insert(u<<1|1,mid+1,r,x,del);
		pushup(u);
	}
}T;
int main() {
	#ifdef LOCAL
	freopen("in.txt","r",stdin);
	freopen("my.out","w",stdout);
	#else
	freopen("set.in","r",stdin);
	freopen("set.out","w",stdout);
	#endif
	read(q);
	rep(i,1,q) {
		read(op),read(d),read(a),read(b);
		qu[i]={op,d,{a,b}};
		if(op) t[++cnt]={d,{a,b}};
	}
	sort(t+1,t+cnt+1);
	rep(i,1,q) {
		int op=qu[i].op,d=qu[i].d;
		pii x=qu[i].x;
		int pos=lower_bound(t+1,t+cnt+1,(node){d,x})-t;
		T.insert(1,1,cnt,pos,op==0);
		uint ans=T.tr[1];
		if(ans==inf) puts("-1");
		else write(ans,'\n');
	}
}

标签:ch,int,max,top,多重集,BC2402C,最小值,set,define
From: https://www.cnblogs.com/liyixin0514/p/18467800

相关文章

  • JedisCluster 中psetex()方法如何使用
    JedisCluster 中的 psetex 方法用于设置一个键值对,并同时设置该键的过期时间(以毫秒为单位)。与 setex 的区别在于 psetex 接受的过期时间是以毫秒为单位,而 setex 接受的是以秒为单位。psetex方法说明方法签名:publicStringpsetex(Stringkey,longmilliseconds......
  • iOS Swift 集合类型 (Array、Set 和 Dictionary ) 与 元组
    语言提供数组(Array)、集合(Set)和字典(Dictionary)三种基本的集合类型用来存储集合数据。数组是有序数据的集。集合是无序无重复数据的集。字典是无序的键值对的集。Swift中的数组、集合和字典必须明确其中保存的键和值类型,这样就可以避免插入一个错误数据类型的值。同理,对于获......
  • 【题解】Solution Set - NOIP2024集训Day50 图的连通性相关
    【题解】SolutionSet-NOIP2024集训Day50图的连通性相关https://www.becoder.com.cn/contest/5618「JSOI2012」越狱老虎桥简述题意:题目大意:给定一张图,A先添加\(1\)条边,B再删去一条边使得图不连通,A要最大化删除边的权值,B要最小化删除边的权值,问最终的权值是多少。......
  • PHP unset() 函数的作用
    PHP中的unset()函数用于销毁指定的变量。具体来说,它会解除变量名与其数据之间的关联,从而释放该变量所占用的内存。不过需要注意的是,unset()并不是删除变量的内容,而是取消对变量名的引用。如果变量是数组中的某个元素或者对象中的某个属性,unset()也会将其从数组或对象中移......
  • codeforces round 977 (div.2) C2(访问set的第一个元素,观察数据规律-出现次序,用set记
    解题历程:我首先想到的是等效法,每一次操作可以等效为每次将第一个人抽出放入一组,后面的人往前移,而该组的人就是可以任意放置的人,当b中后面再出现与前一个相同的人时,就不进行操作,当b中出现不同的人时,就看看这组中有没有这个人,有的话就下一个循环,没有的话就看看这个新的人是否按a中......
  • Java中的Iterator接口,以及HashSet和TreeSet
    在Java编程中,`Iterator`接口是一个非常重要的概念,它为我们提供了一种统一且方便的方式来遍历集合(如`List`、`Set`、`Map`等数据结构中的元素,不过遍历`Map`时稍显特殊,通常是遍历其键值对的集合视图)。##一、Iterator接口的定义与方法`Iterator`接口位于`java.util`包中,它定义......
  • day07=集合进阶(Set、Map集合)
    day07——集合进阶(Set、Map集合)一、Set系列集合1.1认识Set集合的特点Set集合是属于Collection体系下的另一个分支,它的特点如下图所示下面我们用代码简单演示一下,每一种Set集合的特点。//Set<Integer>set=newHashSet<>(); //无序、无索引、不重复//Set<Integer>set=......
  • ab压测的选项、示例和主要关注的指标意义以及ab压测问题Connection reset by peer (10
    一、ab压测的选项、示例和主要关注的指标意义1.ab压测的一些选项-nrequests    全部请求数-cconcurrency 并发数-ttimelimit   最传等待回应时间-ppostfile    POST数据文件-Tcontent-typePOSTContent-type-vverbosity   Howmuchtroubl......
  • 【代码】集合set
    哈喽大家好,我是@学霸小羊,今天来讲一讲集合(set)。在数学上,集合长这样:那今天就来讲一讲编程上的集合。集合的定义:把一些元素按照某些规律放在一起,就形成了一个集合。比如说每个班级就是一个集合,竞赛班也是一个集合,每间学校也是一个集合,等等。集合的特点:确定性、互异性、无序......
  • Windows平台软件打包工具(inno setup)的使用
    目录Windows平台软件打包工具(innosetup)的使用innosetup中文版下载地址innosetup介绍软件特色Innosetup打包教程Windows平台软件打包工具(innosetup)的使用innosetup中文版下载地址正版下载:https://jrsoftware.org/isdl.php中文版下载:链接:https://pan.baidu.com/s/1Bwg......