首页 > 其他分享 >arc166D 做题小计

arc166D 做题小计

时间:2024-04-20 10:22:53浏览次数:31  
标签:return int ll tr 小计 做题 mp arc166D define

线段树做法,拿下你谷最劣解。

题意翻译很形象,就不说了。

思路

最大化最小值,我们很容易想到二分答案。很容易发现,答案具有单调性。

我们二分一个答案 \(x\) ,强制每次使用的区间长度都不小于 \(x\) ,然后判断可行性。

现在问题转化为怎么判断一个答案 \(x\) 是否可行。

我们发现,如果枚举左端点 \(l_i\) ,右端点的取值是在一个范围内的,即 \(r_i\in[p_i,n]\) ,然后 \(p_i\) 我们可以通过二分快速计算出来。不难发现 \(p_i\) 也是单调递增的。

现在问题转化为,可以选若干个区间 \([l,r]\) ,将区间内的所有数都减 \(1\) ,问最终是否能使所有数变为 \(0\) 。

区间减 \(1\) 比较难维护,考虑问题的等价转化,转成差分数组,我们引入 \(d\) 数组,令 \(d_i=b_i-b_{i-1}\) ,所有数为 \(0\) 等价于 \(\forall i\in[1,n],d_i=0\) ,为了程序写的方便,我们引入点 \(x_{n+1}=inf\) ,并且规定 \(d_{n+1}\) 取任意数均可。

然后问题又转化成,可以在 \([1,l_i]\) 中选一个 \(d_x\) 将其减一,在 \([p_i+1,n]\) 中选一个 \(d_x\) 使其加一。

我们从 \(1\) 到 \(n\) 遍历 ,如果遇见某一位是负数,那么就是非法的,所以有一个比较明显的贪心策略:

  • 从 \(1\) 到 \(n\) 遍历 \(d_i\) ,如果 \(d_i<0\) 返回情况非法,否则,贪心的选择 \(j\in[p+1,n]\) 内当前的数和最左边的负数 \(d_j\),使其变为正数,并在 \(d_i\ge 0\) 的条件下。

贪心正确性显然,交换证明即可,可自己尝试。

最后,使用线段树动态维护最左边的负数即可。当然,使用 multiset 也可,或者一个队列维护,但是不太想写了。

使用线段树和二分,所以时间复杂度 \(O(n\log n\log w)\),强势拿下最劣解

code

#include<bits/stdc++.h>
#define mp make_pair
#define N 200005
#define ll long long 
#define Pr pair<ll,int>
#define fi first
#define se second
using namespace std;
const ll inf=1e10;
int n;
ll a[N],b[N],t[N];
ll d[N];
struct segtree{
	Pr tr[N*4];
	void Pushup(int x)
	{
		if(tr[x*2].fi>=0) tr[x]=tr[x*2+1];
		else tr[x]=tr[x*2];
	}
	void modify(int l,int r,int P,int x,ll v)
	{
		if(l==r)
		{
			tr[x]=mp(v,l);
			return;
		}
		int mid=(l+r)/2;
		if(P<=mid) modify(l,mid,P,x*2,v);
		else modify(mid+1,r,P,x*2+1,v);
		Pushup(x);
	}
	Pr query(int l,int r,int L,int R,int x)
	{
		if(l>R||r<L) return mp(inf,-1);
		if(l>=L&&r<=R) return tr[x];
		int mid=(l+r)/2;
		Pr lv=query(l,mid,L,R,x*2),rv=query(mid+1,r,L,R,x*2+1);
		if(lv.fi>=0) return rv;
		else return lv;
	}
}tr;
bool check(ll x)
{
	memcpy(b,t,sizeof t);
	for(int i=1;i<=n;i++) tr.modify(1,n,i,1,b[i]); 
	for(int i=1;i<=n;i++)
	{
		if(b[i]<0) return 0;
		int p=upper_bound(a,a+1+n,a[i-1]+1+x)-a;// p->n 
		while(b[i])
		{
			Pr t=tr.query(1,n,p,n,1);
			ll mv=t.first;
			int mp=t.second;
			if(mv>=0) break;
			if(mv+b[i]>0) b[i]+=mv,b[mp]=0,tr.modify(1,n,mp,1,0),tr.modify(1,n,i,1,b[i]);
			else
			{
				b[mp]+=b[i];
				b[i]=0;
				tr.modify(1,n,mp,1,b[mp]); 
				tr.modify(1,n,i,1,0);
				break;
			}
		}
	}
	return 1;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	for(int i=1;i<=n;i++) scanf("%lld",&t[i]);
	for(int i=n;i>=1;i--) t[i]-=t[i-1];
	a[0]=-inf,a[n+1]=inf;
	ll l=1,r=1e9+5;
	while(l<=r)
	{
		ll mid=(l+r)/2;
		if(check(mid)) l=mid+1;
		else r=mid-1;
	}
	if(l>1e9) printf("-1");
	else printf("%lld",l-1);
	return 0;
}

标签:return,int,ll,tr,小计,做题,mp,arc166D,define
From: https://www.cnblogs.com/g1ove/p/18147282

相关文章

  • [dp 小计] wqs 二分
    天才算法!国外叫Alienstrick(外星人trick),真的太强了。其实是因为IOI2016Aliens这道题考了这个算法才开始普及。解决问题wqs二分一般用来解决如下问题。给定\(n\)个数,求强制选\(m\)个的价值最大。如果不是强制选\(m\)个,这类问题很好做。现在问题就是怎么取消......
  • MySQL常用管理命令、常用函数小计
    1、Windows系统是MySQL服务器的关闭、重启 (mysql为服务名)关闭服务:netstopmysql启动服务:netstartmysql 2、连接mysql服务器在cmd窗口执行命令:mysql-h127.0.0.1-P3306-uroot-p -h127.0.0.1:指定主机IP  -P3306:执行mysql服务端口......
  • 【做题纪要】冲刺NOIP逆天题单之字符串篇
    幽默题目,冲刺NOIp全是SA和SAM,冲刺NOIp一不小心把p冲没了,成NOI了甚至有上个题单没有出现的CF评分*3300,幽默YetAnotherLCPProblem题意给出一个长度为\(n\)的字符串\(S\)和\(q\)次询问,每次询问给出一个集合\(A\)和\(B\)求\(\sum\limits_{i\inA}\sum\limits_{j\in......
  • [dp 小计] 决策单调性优化
    我要急眼了,看了一个破博客写错的浪费我两个小时Task1先讲讲最简单的类型。通常,都是一类类似\(f_i=\min_{j=1}^if_j+w(i,j)\)决策单调,字面意思,就是每次取的点都是右移的。先声明一下,四边形不等式是决策单调性的充分不必要条件。只证明充分条件。令\(w\)满足\(w(a,c)+w......
  • 2024 NSSCTF 做题记录
    web[SWPUCTF2021新生赛]easy_sql我可能不知道怎么写参数,但是我会用sqlmap.python3sqlmap.py-u....--dumptestdb另外说一句,直接用--dump-all是很蠢的行为因为可能会dump到mysql的配置数据库,显然对拿到flag没什么帮助。trytouse--dbs.[SWPUCTF2021新生......
  • [DS 小计] 虚树
    概念什么是虚树?通俗的来说,虚树是原树的一些点集组成的树,这些点是一些关键点。在树形dp遍历中,如果每次都遍历整棵树会很浪费时间,这时候虚树就派上用场了。简介虚树的节点有哪些?在dp中,我们建立虚树包含着关键节点和关键节点的任意二者的\(\text{lca}\)。到这里,你已经会......
  • 1st Universal Cup 做题笔记
    Stage1:Shenyanghttps://qoj.ac/contest/1096A只需要考虑每个pair的贡献即可,而相交的pair数量是线性的,因此可以暴力搞,剩下的不相交的pair拿前缀和做就行了,复杂度\(\mathcalO(n\logn)\)。cornercase是当一方的区间全部退化的时候,需要重新计算一下出现的概率。BC......
  • [DS 小计] 点分树
    点分树是一个处理树上距离的优秀DS。它可以快速处理关于一些树上距离问题。引入我们知道,我们在做点分治的时候,每次找到中心,然后将重心所有的相连的边断开,处理子问题。时间复杂度是\(O(n\logn)\)的。但是有些题目让我们搞强制在线,又要求距离为\(k\)的所有和,这时候点分树......
  • 操作系统综合题之“采用二级页表的分页存储管理方式,计算页目录号的位数 和 页大小,给定
    一、问题:某计算机系统的主存按字节编址,逻辑地址和物理地址都是32位,其内存管理采用两级页表的分页存储管理方式。逻辑地址中页号位10位,页内偏移地址为10位。该计算机系统的两级页表结构如下图所示,图中数值均为十进制数1.页目录号的位数为多少?页的大小为多少KB?2.如果页目录项大小......
  • CF1466H 做题记录
    link非常adhoc的题,但是值得一练的好题!一眼下去,我们会发现这个条件真的太过于抽象,根本无法想象。注意到题目给了我们一个关键信息:一个排列组\(\{b_1,b_2,...,b_n\}\)对应唯一的好的分配方案。考虑建立图论模型:每个人的编号向最喜欢的物品编号连边,形成一棵内向基环树森林。......