首页 > 其他分享 >P4198 楼房重建题解

P4198 楼房重建题解

时间:2023-09-03 09:11:08浏览次数:51  
标签:xl 题解 ll P4198 儿子 斜率 ans 楼房 wz

传送门

一眼数据结构。

考虑线段树,记录该区间能看到最多的建筑数量 \(ans_{wz}\) 以及看到区间中最大的斜率(或者说,该区间内最后看到的建筑)\(xl_{wz}\)。

很明显,假如我现在的修改操作是 \((x,y)\),那么会改变 \(\log_n\) 个节点,即包含 \(x\) 的节点,考虑如何修改他们的 \(ans\) 和 \(xl\)。

对于叶子节点,\(ans_{wz}=1,xl_{wz}=\frac{y}{x}\)

对于其他的节点,就是左儿子的答案 \(+\) 右儿子答案中大于左儿子斜率的建筑数量(因为先看到前面的建筑再看到后面的建筑),不妨设此时左儿子最大斜率为 \(xl_{zuo}\)。

很难 \(O(1)\) 求出来,所以考虑 \(O(\log_n)\) 的时间复杂度内求出。

递归找右儿子中大于左儿子斜率的数量,不妨设我们递归到 \([l,r]\) 这个区间。

考虑 \([l,mid]\) 这个区间的最大斜率

\(1\)、这个最大斜率小于等于 \(xl_{zuo}\),那么直接递归右儿子,即 \([mid+1,r]\) 这个区间

\(2\)、这个最大斜率大于 \(xl_{zuo}\),那么递归左儿子,返回的答案加上\(ans_{[l,r]}-ans_{[l,mid]}\)(这个区间没有受到 \((x,y)\) 的影响,所以这个差就是比该区间内右儿子答案大于左儿子斜率的建筑数量)。

最后的时间复杂度就是 \(O(n \log^2 n)\)

上代码:

#include<bits/stdc++.h>
#define ll long long
#define db double
using namespace std;
const ll N=1e5+50;
ll n,m,ans[N*4];
db xl[N*4];
ll query(ll wz,ll l,ll r,db x)
{
	if(xl[wz]<=x) return 0;
	if(l==r) return (xl[wz]>x);
	ll mid=(l+r)/2;
	if(xl[wz*2]<=x) return query(wz*2+1,mid+1,r,x);
	return query(wz*2,l,mid,x)+ans[wz]-ans[wz*2];
}
void change(ll wz,ll l,ll r,ll md,db x)
{
	if(l==r)
	{
		ans[wz]=1;
		xl[wz]=x;
		return ;
	}
	ll mid=(l+r)/2;
	if(md<=mid) change(wz*2,l,mid,md,x);
	else change(wz*2+1,mid+1,r,md,x);
	xl[wz]=max(xl[wz*2],xl[wz*2+1]);
	ans[wz]=ans[wz*2]+query(wz*2+1,mid+1,r,xl[wz*2]);
}
int main()
{
	scanf("%lld %lld",&n,&m);
	for(ll i=1,x,y;i<=m;i++)
	{
		scanf("%lld %lld",&x,&y);
		change(1,1,n,x,(db)y/x);
		printf("%lld\n",ans[1]);
	}
	return 0;
}

标签:xl,题解,ll,P4198,儿子,斜率,ans,楼房,wz
From: https://www.cnblogs.com/pengchujie/p/17674584.html

相关文章

  • AT_abc318_e 题解
    AT_abc318_eSandwiches题解Links洛谷AtCoderDescription给定一个长度为\(n\)的序列\(a\),找到满足以下条件的三元组\((a,b,c)\)的数量。\(i<j<k\);\(a_{i}=a_{k}\);\(a_{i}\neqa_{j}\)。数据范围:\(1\leqn\leq3\times10^{5}\),\(1\leqa_{i}\leqn......
  • ABC317题解报告
    我直接从第三题开始讲了。T3把数组\(A\)从大到小排序。然后从前往后把前\(q\)个数加起来,然后判断这\(q\)个数的和与\(d\)的大小关系,如果大了就变成\(d\)。然后有些细节就看代码吧。#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;constintm......
  • 龙芯平台Hadoop集群搭建问题解决
    这几天一直在困扰我pycurl版本和本机的版本不符合他连接又连接的自己自带的版本与系统不相同低级也会报错 https://blog.csdn.net/u010910682/article/details/89496550/?ops_request_misc=&request_id=&biz_id=102&utm_term=pycurl7.45.2%20%E6%90%AD%E9%85%8Dlibcurl%E6%......
  • 【题解】NOIP2021
    咕咕咕的东西总是要补的。A.报数题目描述:报数游戏是一个广为流传的休闲小游戏。参加游戏的每个人要按一定顺序轮流报数,但如果下一个报的数是\(7\)的倍数,或十进制表示中含有数字\(7\),就必须跳过这个数,否则就输掉了游戏。在一个风和日丽的下午,刚刚结束SPC20nn比赛的小r和......
  • 【题解】Luogu[P7706] 「Wdsr-2.7」文文的摄影布置
    Link一道很有意思的线段树题。第一步分析,我们要求最大的\(a_i+a_k-\min{(b_j)}\),事实上我们可以直接省去这个\(\min\)因为要最大化这个东西,选出来的\(b_j\)必然是最小的,所以原题转化为给定\(l,r\)求\(\max{(a_i-b_j+a_k)}\)其中\(i<j<k\)。第二步分析,我们发现这是一......
  • 【题解】Educational Codeforces Round 153(CF1860)
    每次打都想感叹一句,Educational名不虚传。A.NotaSubstring题目描述:有\(t\)组数据,对于每一组数据,你需要判断能否构造一个只由左右括号组成且长度为已经给定字符串的\(2\)倍且已经给定的字符串不是子串的合法字符串。注:合法的字符串是左右括号能完全匹配的字符串。如果能,......
  • 【题解】Luogu-P2482 SDOI2010 猪国杀
    写了\(358\)行,\(11.94\mathrm{KB}\),有这么几个地方写挂了:反猪决斗一定选主猪。游戏结束判定是主猪死亡或全部反猪死亡。决斗可能被反杀,之后不能再出牌。点击查看代码#include<bits/stdc++.h>usingnamespacestd;intn,m;charCh[3];queue<char>Deck;in......
  • CF1863C 题解
    CF1863CMEXRepetition题解Links洛谷CodeforcesDescription给你一个长度为\(n\)的序列\(a\),满足\(\foralli\in[1,n]\),\(0\leqa_{i}\leqn\)且序列中的数互不相同。定义一次操作为:按照\(i\)从\(1\)到\(n\)的顺序,\(a_{i}\gets\operatorname{MEX}(a_{1}......
  • CF1863B 题解
    CF1863BSplitSort题解Links洛谷CodeforcesDescription给定一个\(1\simn\)的排列\(q\),你可以多次进行以下操作:新建一个初始为空的序列\(q\);选择一个整数\(x\)(\(2\leqx\leqn\));按照在\(p\)中出现的顺序将所有小于\(x\)的数添加到序列\(q\)末尾。按照在......
  • P1463 [POI2001] [HAOI2007] 反素数 题解
    P1463[POI2001][HAOI2007]反素数题解可以发现,最大的不超过\(n\)的反素数就是\(1\simn\)中因数最多的数字。证明:设\(x,x\in[1,n]\)为\(1\simn\)中因数最多的数字,则\(x<y\len\)都不会成为答案,因为存在\(x<y\)因数比\(y\)多,同时也不会存在\(y'<x\)......