题意:

n个点,分成两组A,B,如果点i在A中,那么贡献值\(a_i\),反之为\(b_i\)。

现要求任意\(i \in A,j \in B\)不存在 \(x_i >= x_j\) 且 \(y_i <= y_j\),也就是说A中点不在B中点的右下方。

思路:

https://blog.nowcoder.net/n/7205418146f3446eb0b1ecec8d2ab1da

代码:

#include<cmath>
#include<set>
#include<map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e5 + 5;
const int M = 50 + 5;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const int MOD = 1000000007;
struct Node{
int x, y, a, b;
}p[maxn];
bool cmp(Node x, Node y){
if(x.x == y.x) return x.y > y.y;
return x.x < y.x;
}
vector<int> vv;
ll Max[maxn << 2], lazy[maxn << 2];
void pushup(int rt){
Max[rt] = max(Max[rt << 1], Max[rt << 1 | 1]);
}
void pushdown(int rt){
if(lazy[rt]){
lazy[rt << 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
Max[rt << 1] += lazy[rt];
Max[rt << 1 | 1] += lazy[rt];
lazy[rt] = 0;
}
}
void build(int l, int r, int rt){
Max[rt] = lazy[rt] = 0;
if(l == r) return;
int m = (l + r) >> 1;
build(l, m, rt << 1);
build(m + 1, r, rt << 1 | 1);
}
void update(int L, int R, int l, int r, int v, int rt){
if(L > R) return;
if(L <= l && R >= r){
Max[rt] += v;
lazy[rt] += v;
return;
}
pushdown(rt);
int m = (l + r) >> 1;
if(L <= m)
update(L, R, l, m, v, rt << 1);
if(R > m)
update(L, R, m + 1, r, v, rt << 1 | 1);
pushup(rt);
}
void change(int pos , int l, int r, ll v, int rt){
if(l == r){
Max[rt] = max(Max[rt], v);
return;
}
pushdown(rt);
int m = (l + r) >> 1;
if(pos <= m)
change(pos, l, m, v, rt << 1);
else
change(pos, m + 1, r, v, rt << 1 | 1);
pushup(rt);
}
ll query(int L, int R, int l, int r, int rt){
if(L <= l && R >= r){
return Max[rt];
}
pushdown(rt);
int m = (l + r) >> 1;
ll MAX = -1;
if(L <= m)
MAX = max(MAX, query(L, R, l, m, rt << 1));
if(R > m)
MAX = max(MAX, query(L, R, m + 1, r, rt << 1 | 1));
pushup(rt);
return MAX;
}
int main(){
int n;
while(~scanf("%d", &n)){
vv.clear();
for(int i = 1; i <= n; i++){
scanf("%d%d%d%d", &p[i].x, &p[i].y, &p[i].a, &p[i].b);
vv.push_back(p[i].y);
}
vv.push_back(-1);
sort(vv.begin(), vv.end());
vv.erase(unique(vv.begin(), vv.end()), vv.end());
for(int i = 1; i <= n; i++) p[i].y = lower_bound(vv.begin(), vv.end(), p[i].y) - vv.begin() + 1; sort(p + 1, p + n + 1, cmp);
build(1, vv.size(), 1);
for(int i = 1; i <= n; i++){
ll tmp = query(1, p[i].y, 1, vv.size(), 1);
update(p[i].y, vv.size(), 1, vv.size(), p[i].b, 1);
update(1, p[i].y - 1, 1, vv.size(), p[i].a, 1);
change(p[i].y, 1, vv.size(), tmp + p[i].b, 1);
}
printf("%lld\n", Max[1]);
}
return 0;
}

最新文章

  1. 查看应用程序使用的所有dll
  2. Emmet (Zen Coding) 官方文档中HTML语法的总结
  3. Ada语言基础
  4. memcached学习笔记2--安装及命令
  5. vi编辑文件E437: terminal capability "cm" required 解决办法
  6. Java Se 基础系列(笔记) -- OO
  7. 实战Lucene,初始Lucene
  8. string 到 wstring的转换
  9. Java Date 和 Calendar
  10. Swift供选链接
  11. CSS3 filter(滤镜) 属性
  12. 导航条css实现和table实现
  13. iOS-UI控件优化
  14. MySQL DATEDIFF() 函数
  15. Python:Day09
  16. MFC文件处理
  17. ajax readystatue
  18. MySQL数据类型之字符串类型
  19. 关于等效的物理意义 On the Physical Meaning of Equivalence
  20. python中 除了if else def class 有作用域 其余没有作用域

热门文章

  1. Poj-P3468题解【线段树】
  2. LSTM+CRF进行序列标注
  3. luoguP2016 战略游戏
  4. [Usaco2008 Mar]River Crossing渡河问题
  5. JVM(四)打破双亲委派和SPI机制
  6. JVM重新认识(一)oop-klass模型--HSDB使用验证
  7. 从源码解析Nginx对 Native aio支持_运维_youbingchen的博客-CSDN博客 https://blog.csdn.net/youbingchen/article/details/51767587
  8. gitignore 不起作用的解决办法 不再跟踪 让.gitignore生效,跟踪希望被跟踪的文件
  9. HTTPS学习(二):原理与实践
  10. 【Coursera】Internet History 读书笔记