Points Division(线段树+DP)2019牛客暑期多校训练营(第一场)
题意:https://ac.nowcoder.com/acm/contest/881/I
给你n个平面上的点,每个点有a、b两个权值,现在让你划分成两个区域(要求所有A集合里的点不能在任何B集合里的点的右下方)。
求MAX(Sigma ai+Sigma bi)。
思路:
dp+线段树。
https://blog.csdn.net/qq_41194925/article/details/97079075
就是有一个要注意的地方:对于枚举的点我们算的是B集合所以dp【i】=max(1~i)+bi,这里必须是bi。
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#include <cstdio>//sprintf islower isupper
#include <cstdlib>//malloc exit strcat itoa system("cls")
#include <iostream>//pair
#include <fstream>//freopen("C:\\Users\\13606\\Desktop\\草稿.txt","r",stdin);
#include <bitset>
//#include <map>
//#include<unordered_map>
#include <vector>
#include <stack>
#include <set>
#include <string.h>//strstr substr
#include <string>
#include <time.h>//srand(((unsigned)time(NULL))); Seed n=rand()%10 - 0~9;
#include <cmath>
#include <deque>
#include <queue>//priority_queue<int, vector<int>, greater<int> > q;//less
#include <vector>//emplace_back
//#include <math.h>
//#include <windows.h>//reverse(a,a+len);// ~ ! ~ ! floor
#include <algorithm>//sort + unique : sz=unique(b+1,b+n+1)-(b+1);+nth_element(first, nth, last, compare)
using namespace std;//next_permutation(a+1,a+1+n);//prev_permutation
//******************
int abss(int a);
int lowbit(int n);
int Del_bit_1(int n);
int maxx(int a,int b);
int minn(int a,int b);
double fabss(double a);
void swapp(int &a,int &b);
clock_t __STRAT,__END;
double __TOTALTIME;
void _MS(){__STRAT=clock();}
void _ME(){__END=clock();__TOTALTIME=(double)(__END-__STRAT)/CLOCKS_PER_SEC;cout<<"Time: "<<__TOTALTIME<<" s"<<endl;}
//***********************
#define rint register int
#define fo(a,b,c) for(rint a=b;a<=c;++a)
#define fr(a,b,c) for(rint a=b;a>=c;--a)
#define mem(a,b) memset(a,b,sizeof(a))
#define pr printf
#define sc scanf
#define ls rt<<1
#define rs rt<<1|1
typedef long long ll;
//#define int ll
const double E=2.718281828;
const double PI=acos(-1.0);
//const ll INF=(1LL<<60);
const int inf=(<<);
const double ESP=1e-;
const int mod=(int)1e9+;
const int N=(int)1e6+; struct node
{
int x,y,va,vb;
friend bool operator<(node a,node b)
{
if(a.x==b.x)
return a.y>b.y;
return a.x<b.x;
}
}a[N];
int temp[N];
int LS(int n)
{
int m=;
for(int i=;i<=n;++i)
temp[++m]=a[i].y;
sort(temp+,temp++m);
m=unique(temp+,temp++m)-temp-;
for(int i=;i<=n;++i)
a[i].y=lower_bound(temp+,temp++m,a[i].y)-temp;
return m;
} ll add[N<<],max_[N<<]; void up(int rt,int l,int r)
{
max_[rt]=max(max_[rt<<],max_[rt<<|]);
} void dn(int rt)
{
if(add[rt]!=)
{
add[ls]+=add[rt];
add[rs]+=add[rt];
max_[rt<<]+=add[rt];
max_[rt<<|]+=add[rt];
add[rt]=;
}
} void Build(int l,int r,int rt)
{
max_[rt]=;
add[rt]=;
if(l==r)
{
return;
}
int mid=(l+r)>>; Build(l,mid,rt<<);
Build(mid+,r,rt<<|);
up(rt,l,r);
} void update_dot(int pos,ll V,int l,int r,int rt)
{
if(l==r)
{
max_[rt]=V;
return;
} int mid=(l+r)>>;
dn(rt);
if(pos<=mid)
update_dot(pos,V,l,mid,rt<<);
else
update_dot(pos,V,mid+,r,rt<<|);
up(rt,l,r);
}
void update_qu(int L,int R,int V,int l,int r,int rt)
{
if(L>R)return;
if(L<=l&&r<=R)
{
max_[rt]+=V;
add[rt]+=V;
return;
} int mid=(l+r)>>;
dn(rt);
if(L<=mid)
update_qu(L,R,V,l,mid,rt<<);
if(R>mid)
update_qu(L,R,V,mid+,r,rt<<|);
up(rt,l,r);
}
ll Query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return max_[rt];
int mid=(l+r)>>;
ll res=;
dn(rt);
if(L<=mid)
res=max(res,Query(L,R,l,mid,rt<<));
if(R>mid)
res=max(res,Query(L,R,mid+,r,rt<<|));
return res;
}
void check(int pos,int l,int r,int rt)
{
if(l==r)
{
cout<<max_[rt]<<' ';
return ;
}
int mid=(l+r)>>; dn(rt);
if(pos<=mid)
check(pos,l,mid,rt<<);
else
check(pos,mid+,r,rt<<|);
} signed main()
{
int n;
while(~sc("%d",&n))
{
for(int i=;i<=n;++i)
{
int q,w,e,r;
sc("%d%d%d%d",&q,&w,&e,&r);
a[i]={q,w,e,r};
}
int tot=LS(n);
sort(a+,a++n);
Build(,tot,);
for(int i=;i<=n;++i)
{
// a[i].y++;
ll max__=Query(,a[i].y+,,tot,);
update_dot(a[i].y,max__+a[i].vb,,tot,);
update_qu(,a[i].y-,a[i].va,,tot,);
update_qu(a[i].y+,tot,a[i].vb,,tot,);
// for(int j=0;j<=tot;++j)
// check(j,0,tot,1);
// cout<<endl;
}
pr("%lld\n",max_[]);
}
return ;
} /**************************************************************************************/ int maxx(int a,int b)
{
return a>b?a:b;
} void swapp(int &a,int &b)
{
a^=b^=a^=b;
} int lowbit(int n)
{
return n&(-n);
} int Del_bit_1(int n)
{
return n&(n-);
} int abss(int a)
{
return a>?a:-a;
} double fabss(double a)
{
return a>?a:-a;
} int minn(int a,int b)
{
return a<b?a:b;
}
Points Division(线段树+DP)2019牛客暑期多校训练营(第一场)的更多相关文章
- 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)
题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...
- 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem
题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3 4 2 3 4 输出:0 0 1 题解: 认真想一 ...
- 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题)
layout: post title: 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题) author: "luowentaoaa" c ...
- 2019牛客暑期多校训练营(第一场)I dp+线段树
题意 给出n个点,每个点有a,b两个属性,让你从左下角到右上角划一条线,线的左边每个点的贡献是\(a_i\),线的右边每个点的贡献是\(b_i\),使得两部分的总和最大. 分析 找一条折线将点分割开, ...
- 2019牛客暑期多校训练营(第二场)E 线段树维护dp转移矩阵
题意 给一个\(n\times m\)的01矩阵,1代表有墙,否则没有,每一步可以从\(b[i][j]\)走到\(b[i+1][j]\),\(b[i][j-1]\),\(b[i][j+1]\),有两种 ...
- DP+线段树维护矩阵(2019牛客暑期多校训练营(第二场))--MAZE
题意:https://ac.nowcoder.com/acm/contest/882/E 给你01矩阵,有两种操作:1是把一个位置0变1.1变0,2是问你从第一行i开始,到最后一行j有几种走法.你只能 ...
- 2019牛客暑期多校训练营(第八场)E:Explorer(LCT裸题 也可用线段树模拟并查集维护连通性)
题意:给定N,M,然后给出M组信息(u,v,l,r),表示u到v有[l,r]范围的通行证有效.问有多少种通行证可以使得1和N连通. 思路:和bzoj魔法森林有点像,LCT维护最小生成树. 开始和队友 ...
- Find the median(线段树+离散化)(2019牛客暑期多校训练营(第七场))
题目出处:Find the median 示例: 输入: 53 1 4 1 5 92 7 1 8 2 9 输出:3 4 5 4 5 说明:L = [3, 2 ,4, 1, 7],R = [4, 8, ...
- sequence(线段树+单调栈) (2019牛客暑期多校训练营(第四场))
示例: 输入: 31 -1 11 2 3 输出: 3 题意:求最大的(a区间最小值*b区间和) 线段树做法:用单调栈求出每个数两边比b数组大的左右边界,然后用线段树求出每段区间的和sum.最小前缀ls ...
随机推荐
- OSI七层参考模型
一.OSI七层模型简述 二.每层的作用 三.数据封装的过程 四.数据解封的过程
- typedef void (*funcptr)(void)的含义
fun a;//等价于void (*a)(); 这样声明起来就方便多了 void (*a)();表示a是个指针,指向一个不带参数.返回值为空的函数 定义一个函数指针类型. 比如你有三个函数: void ...
- go面试
**1**.简述golang中make和new的区别 make用于内建类型(只能用于创建map.slice 和channel)的内存分配.并且返回一个有初始值(非零)的T类型,而不是*T. new用于 ...
- docker crontab踩坑记录
环境,docker centos7.4 容器启动时注意两点 入口要设置/usr/sbin/init,并且配置主机完全访问权限(--privileged) (否则执行service的时候会出现Faile ...
- Nginx之进程间的通信机制(Nginx频道)
1. Nginx 频道 ngx_channel_t 频道是 Nginx master 进程与 worker 进程之间通信的常用工具,它是使用本机套接字实现的,即 socketpair 方法,它用于创建 ...
- SRS之SrsHlsCache::reap_segment详解
1. 是否可切片的检测 首先在调用 SrsHlsCache::reap_segment 函数进行切片时,针对音频或视频,都会有一个函数来进行检测当前片的时长是否符合所要求的时长. 对于音频,会调用 S ...
- 常用css模板
段落超出显示省略号(可单行多行) .p-content{ overflow:hidden; text-overflow:ellipsis; display:-webkit-box; -webkit-b ...
- 解决Android Studio 升级时提示 Connection failed. Please check your network connection and try again问题
一,问题: 无论mac还是windows可能都会出现这个问题,解决方案大同小异,就是修改VMOptions而已. 解决方案: Windows: 在\Android Studio\bin目录下找到 st ...
- Mysql 逗号分隔行列转换总结
方法一 存储过程实现: -- 修改结束符,防止在mysql命令行中默认分号直接运行 delimiter $$ -- 创建一个计算拆分后字符串的个数函数 drop function if exists ...
- 【Makefile】Makefile中的常用函数简介
1. subst函数 格式:$(subst <from>, <to>, <text>)功能:把字串<text>中的<from>字符串替换成& ...