I题  Points Division

题意:

给你n个点,每个点有坐标(xi,yi)和属性(ai,bi),将点集划分为两个集合,

任意 A 集合的点 i 和 B 集合点 j, 不允许 xi >= xj 且 yi <= yj。

A 集合的点使用权值 ai,B 集合的点使用权值 bi​,求:

思路:

可以用一条自底向上的折线将这些点分为两组,折线左上为A集合,右下B集合,折线上的点也属于B集合

dp[i] 代表 当前点i在折线上时权值和的最大值

那么对于当前点i来说:

i点之前,y坐标小于yi的点的dp[i]都要加上权值ai (因为当那些点为折线上的点时,当前点i就会被归为A集合)

y坐标大于yi的点的dp[i]都要加上权值bi(因为当那些点为折线上的点时,当前点i会被归为B集合)

计算当前点的dp[i],因为折线时自底向上的,那么肯定是由当前点下面的点中权值和最大的点max(dp[j])转折的,那么dp[i] = max(dp[j] + bi;

最后取权值和最大

推到这里可以发现需要区间更新,区间最值,单点更新,那么可以直接用线段树来维护。

注意要多加个高度为0的点为折线起始点,这样第一个点就有参照点了,否则无法统计第一个点在折线上和折线下情况的贡献。

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define mid ll m = (l + r) >> 1 const int M = 1e5+;
ll mx[M<<],lazy[M<<];
void up(ll rt){
mx[rt] = max(mx[rt<<],mx[rt<<|]);
} void pushdown(ll rt){
if(lazy[rt]){
lazy[rt<<] += lazy[rt];
lazy[rt<<|] += lazy[rt];
mx[rt<<] += lazy[rt];
mx[rt<<|] += lazy[rt];
lazy[rt] = ;
}
} void build(ll l,ll r,ll rt){
lazy[rt] = ; mx[rt] = ;
if(l == r){
return ;
}
mid;
build(lson); build(rson);
} void update(ll p,ll c,ll l,ll r,ll rt){
if(l == r){
mx[rt] = max(mx[rt],c);
return ;
}
pushdown(rt);
mid;
if(p <= m) update(p,c,lson);
else update(p,c,rson);
up(rt);
} void update1(ll L,ll R,ll c,ll l,ll r,ll rt){
if(L > R) return ; //会出现L > R的情况,需要判下
if(L <= l&&R >= r){
mx[rt] += c;
lazy[rt] += c;
return ;
}
pushdown(rt);
mid;
if(L <= m) update1(L,R,c,lson);
if(R > m) update1(L,R,c,rson);
up(rt);
} ll query(ll L,ll R,ll l,ll r,ll rt){
if(L > R) return ;
if(L <= l&&R >= r){
return mx[rt];
}
pushdown(rt);
mid;
ll ret = ;
if(L <= m) ret = max(ret,query(L,R,lson));
if(R > m) ret = max(ret,query(L,R,rson));
return ret;
} struct node{
ll x,y,a,b;
}v[M];
bool cmp(node aa,node bb){
if(aa.x == bb.x) return aa.y > bb.y;
return aa.x < bb.x;
}
ll t[M];
int main()
{
ll n;
while(scanf("%lld",&n)!=EOF){
ll cnt = ;
for(ll i = ;i <= n;i ++){
scanf("%lld%lld%lld%lld",&v[i].x,&v[i].y,&v[i].a,&v[i].b);
t[++cnt] = v[i].y;
}
sort(t+,t++cnt);
sort(v+,v++n,cmp);
ll m = unique(t+,t++cnt)-t-;
for(ll i = ;i <= n;i ++)
v[i].y = lower_bound(t+,t++m,v[i].y)-t+; //离散化时点都向后移一位
m ++; //点后移了一位,长度要+1;
build(,m,);
for(ll i = ;i <= n;i ++){
ll ans = query(,v[i].y,,m,);
update1(v[i].y+,m,v[i].b,,m,);
update1(,v[i].y-,v[i].a,,m,);
update(v[i].y,ans+v[i].b,,m,);
}
printf("%lld\n",mx[]);
}
return ;
}

2019牛客多校赛第一场 补题 I题的更多相关文章

  1. 2019牛客多校(第一场)F-Random Point in Triangle

    #include <bits/stdc++.h> using namespace std; typedef long long ll; struct Point{ ll x, y; Poi ...

  2. 2019牛客多校第八场 F题 Flowers 计算几何+线段树

    2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...

  3. 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数

    目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...

  4. 2019牛客多校第四场 A meeting

    链接:https://ac.nowcoder.com/acm/contest/884/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K,其他语言10485 ...

  5. 2019牛客多校第五场generator2——BSGS&&手写Hash

    题目 几乎原题 BZOJ3122题解 分析 先推一波公式,然后除去特殊情况分类讨论,剩下就是形如 $a^i \equiv b(mod \ p)$ 的方程,可以使用BSGS算法. 在标准的BSGS中,内 ...

  6. [题解]Magic Line-计算几何(2019牛客多校第三场H题)

    题目链接:https://ac.nowcoder.com/acm/contest/883/H 题意: 给你偶数个点的坐标,找出一条直线将这n个点分成数量相等的两部分 并在这条直线上取不同的两个点,表示 ...

  7. 2019牛客多校第五场H - subsequence 2 拓扑

    H - subsequence 2 题意 要你使用前\(m\)个小写字母构造一个长度为\(n\)的字符串 有\(m*(m-1)/2\)个限制条件: \(c_{1} .c_{2}. len\):表示除去 ...

  8. 2019 牛客多校第六场 D Move

    题目链接:https://ac.nowcoder.com/acm/contest/886/D 题解摘自官方题解 题目大意 有 K 个体积相同的箱子,有 N 个体积相同或相异的物品,现要按照如下策略装箱 ...

  9. 2019牛客多校第七场E Find the median 离散化+线段树维护区间段

    Find the median 题意 刚开始集合为空,有n次操作,每次操作往集合里面插入[L[i],R[i]]的值,问每次操作后中位数是多少 分析 由于n比较大,并且数可以达到1e9,我们无法通过权值 ...

随机推荐

  1. IIS遇到过的问题

    1. IIS的一个莫名错误Server Application Unavailable http://www.kesion.com/zzcd/asp/aspjq/474.html 新打开这个服务ASP ...

  2. Shell 脚本语法

    条件测试:test  和  [ 命令 test 或 [ 可以测试一个条件是否成立,如果测试结果为真,则该命令的Exit Status为0,如果测试结果为假,则命令的Exit Status为1(注意与C ...

  3. CF811E Vladik and Entertaining Flags

    嘟嘟嘟 看题目这个架势,就知道要线段树,又看到维护联通块,那就得并查集. 所以,线段树维护并查集. 然而如果没想明白具体怎么写,就会gg的很惨-- 首先都容易想到维护区间联通块个数和区间端点两列的点, ...

  4. redis系列(二):数据操作

    1.string类型 字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等.在Redis中 ...

  5. python编写弹球游戏的实现代码

    #coding:utf- from tkinter import * import random import time class Ball: #创建一个球类 def __init__(self, ...

  6. 软件构造实验二-拷贝一个c文件 将其中的关键字int替换成float

    1,新建 Parser Generator 点击project --> new 2,填写工程名字 随意取一个名字 点击OK 3,点击Project选项下的 parserwizard 分析器向导选 ...

  7. 跨域方案JSONP与CORS的各自优缺点以及应用场景

    转自 https://www.zhihu.com/question/41992168/answer/217903179 首先明确:JSONP与CORS的使用目的相同,并且都需要服务端和客户端同时支持, ...

  8. js中判断对象类型的几种方法

    我们知道,JavaScript中检测对象类型的运算符有:typeof.instanceof,还有对象的constructor属性: 1) typeof 运算符 typeof 是一元运算符,返回结果是一 ...

  9. Linux 之Shell for循环

    @代表所有参数所以如果后面跟上echo $v你会发现他会一次显示user userdebug eng $poo -le ${#prodlist[@]} 这句话是说 $poo小于等于prodlist中的 ...

  10. cs6.8-oracle挂载ceph

    https://ceph-users.ceph.narkive.com/EgcYJhbG/hammer-0-94-1-still-getting-feature-set-mismatch-for-ce ...