bzoj2957 奥妙重重的线段树
https://www.lydsy.com/JudgeOnline/problem.php?id=2957
线段树的query和update竟然还可以结合起来用!
题意:小A的楼房外有一大片施工工地,工地上有N栋待建的楼房。每天,这片工地上的房子拆了又建、建了又拆。他经常无聊地看着窗外发呆,数自己能够看到多少栋房子。
  为了简化问题,我们考虑这些事件发生在一个二维平面上。小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度。如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线段相交,那么这栋楼房就被认为是可见的。
  施工队的建造总共进行了M天。初始时,所有楼房都还没有开始建造,它们的高度均为0。在第i天,建筑队将会将横坐标为Xi的房屋的高度变为Yi(高度可以比原来大---修建,也可以比原来小---拆除,甚至可以保持不变---建筑队这天什么事也没做)。请你帮小A数数每天在建筑队完工之后,他能看到多少栋楼房?
开始考虑离线操作,但是后来发现这是一个三维问题,寻找x1 < x2,y1 < y2,t1 < t2的最长序列,其中x的为位置,y为斜率,t为询问的顺序,但是因为不求他的对数,觉得不能用cdq分治来做,所以考虑线段树。
当一个点发生修改的时候,对左区间是没有影响的,对右区间的影响是左区间的最大值一下的所有点都不计入sum。
考虑维护一个sum和max即可。
说不定我以后可以想到cdq分治的解法。嘿嘿嘿。
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
inline int read(){int now=;register char c=getchar();for(;!isdigit(c);c=getchar());
for(;isdigit(c);now=now*+c-'',c=getchar());return now;}
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
const double eps = 1e-;
const int maxn = 1e5 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int N,M,K;
struct Tree{
int l,r;
double mx;
int sum;
}tree[maxn << ];
void Build(int t,int l,int r){
tree[t].l = l;
tree[t].r = r;
if(r == l){
tree[t].mx = tree[t].sum = ;
return;
}
int m = (l + r) >> ;
Build(t << ,l,m);
Build(t << | ,m + ,r);
}
int query(int t,double mx){
if(tree[t].mx <= mx) return ;
if(tree[t].l == tree[t].r) return ;
int m = (tree[t].l + tree[t].r) >> ;
if(tree[t << ].mx <=mx) return query(t << | ,mx);
else return query(t << ,mx) + tree[t].sum - tree[t << ].sum;
}
void Pushup(int t){
tree[t].mx = max(tree[t << ].mx,tree[t << | ].mx);
tree[t].sum = tree[t << ].sum + query(t << | ,tree[t << ].mx);
}
void update(int t,int x,double k){
if(tree[t].l == tree[t].r){
tree[t].sum = ;;
tree[t].mx = k;
return;
}
int mid = (tree[t].l + tree[t].r ) >> ;
if(x <= mid) update(t << ,x,k);
else update(t << | ,x,k);
Pushup(t);
}
int main()
{
Sca2(N,M);
Build(,,N);
For(i,,M){
int x,y; Sca2(x,y);
double t = y * 1.0 / x;
update(,x,t);
Pri(tree[].sum);
}
#ifdef VSCode
system("pause");
#endif
return ;
}
bzoj2957 奥妙重重的线段树的更多相关文章
- [BZOJ2957] 楼房重建 (线段树,递归)
		题目链接 Solution 经典的一道线段树题,难点在于如何合并节点. 由于题目要求直线要求不相交,则斜率均大于前面的点即为答案. 所以以斜率为权值. 考虑线段树每一个节点维护两个值: \(Max\) ... 
- bzoj2957楼房重建——线段树
		题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2957 线段树维护原点到楼顶的斜率,可以知道答案就是从原点开始斜率递增的个数: 记录一个mx数 ... 
- bzoj2957 楼房重建——线段树
		题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2957 线段树维护两个值:cnt 能看到的最多楼房数: mx 最大斜率数: 对于一段区间,从左 ... 
- [bzoj2957][楼房重建] (线段树)
		Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ... 
- 【BZOJ2957】楼房重建(线段树)
		[BZOJ2957]楼房重建(线段树) 题面 BZOJ 题解 对于整个区间维护最大斜率以及只考虑这个区间的答案 考虑如何向上合并. 首先左半段的答案是一定存在的 所以,现在的问题就是右半段能够贡献的答 ... 
- BZOJ2957 楼房重建  【线段树】
		题目 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些事件发生在一个二维 ... 
- 【bzoj2957】【楼房重建】另类的线段树(浅尝ACM-H)
		[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=62609346 向大(hei)佬(e)势力学(di ... 
- bzoj4034 线段树+dfs序
		https://www.lydsy.com/JudgeOnline/problem.php?id=4034 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 ... 
- 论一类每次修改log个结点更新的线段树标记方法
		楼房重建(BZOJ2957) 多次询问一个区间中大于区间内这个数之前所有数的数的数量. 每个线段树结点维护该节点的答案c和区间内最大值m.假设有函数get(x,cm)=结点x中答案>cm的长度. ... 
随机推荐
- 遍历map中的内容
			Map<String, CartItem> cartItems = cart.getCartItems();for(Map.Entry<String, CartItem> en ... 
- 如何在虚拟机下配置centOS7
			链接地址:https://baijiahao.baidu.com/s?id=1597320700700593557&wfr=spider&for=pc 
- 高度可配置的 Linux 内存守护程序 Nohang!
			导读 Nohang 是一个 Linux 守护程序,也是一个高度可配置的 OOM(内存溢出)阻止工具,适用于 Linux 系统,能够有效地防止内存不足的情况. 部分功能特性 具有良好注释的配置文件,配置 ... 
- 趣味网站5个,小鸡词典/中国配色/名著地图/海洋之音/LOGO设计
			一.小鸡词典 很多流行的词语还没有收录到各大词典,却可以在小鸡词典搜索到,小鸡词典是最全的网络流行词语词典. 不少词条搞笑无厘头,撰写词条还会获得红包. 访问地址:https://jikipedia. ... 
- OneinStack——PHP多版本共存
			前言 我事先安装的是LNMP环境,PHP版本为7.2,但是现在环境需要一个PHP5.6,所以就准备安装个上版本,顺带写个安装教程,写完后我发现了原来有直接安装的命令!所以后面的内容大家可以忽略了!从配 ... 
- CH0805 防线(算竞进阶习题)
			二分 一道藏的很深的二分题... 题目保证只有一个点有奇数个防具,这个是突破口. 因为 奇数+偶数=偶数,我们假设某个点x,如果有奇数点的防具在x的左边,那么x的左边的防具总数一定是奇数,右边就是偶数 ... 
- Edge Deletion CodeForces - 1076D(水最短路)
			题意: 设从1到每个点的最短距离为d,求删除几条边后仍然使1到每个点的距离为d,使得剩下的边最多为k 解析: 先求来一遍spfa,然后bfs遍历每条路,如果d[v] == d[u] + Node[i] ... 
- Marriage Match IV HDU - 3416(最短路 + 最大流)
			题意: 求有多少条最短路 解析: 正着求一遍最短路 得dis1 反着求一遍得 dis2 然后 遍历所有的边 如果 dis1[u] + dis2[v] + w == dis1[B], 则说明这是一 ... 
- Node<T> 的作用
			Java中常见到以下定义的类 public class Node<T> { T data; public Node<T> next; Node(T data) { this.d ... 
- C#常用的命名规则汇总
			C#常用的命名规则汇总 来源 https://www.cnblogs.com/pengyouqiang88/p/5021128.html 本文转载自脚本之家 本文详细汇总了C#常用的命名规则.分享给大 ... 
