Man Down(线段树dp)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Man Down(线段树dp)相关的知识,希望对你有一定的参考价值。
Man Down(线段树dp)
是男人就下100层的模拟,因为每个平台往左和往右的状态是确定的,这可以通过线段树的区间覆盖,单点查询求,然后就是从高往低dp。
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
区间覆盖不需要 l a z t t a g lazt \\ tag lazt tag,换句话说 a [ x ] . c o l o r a[x].color a[x].color 就是 l a z y t a g lazy \\ tag lazy tag
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
//区间修改 区间求和
#define il inline
#define lx x<<1
#define rx x<<1|1
#define len(x) (a[x].r-a[x].l+1)
struct node{
int l,r;
int s;
}a[N<<2];
il void re(int x){
if(a[lx].s==a[rx].s) a[x].s=a[lx].s;
else a[x].s=0;
}
il void ptg(int x,int y){
a[x].s=y;
}
il void pd(int x){
if(a[x].s){
ptg(lx,a[x].s),ptg(rx,a[x].s);
a[x].s=0;
}
}
il void bud(int x,int l,int r){
a[x].l=l,a[x].r=r,a[x].s=0;
if(l==r){
return;
}
int m=(l+r)>>1;bud(lx,l,m),bud(rx,m+1,r);
}
il void upd(int x,int l,int r,int val){
if(a[x].l>=l&&a[x].r<=r){
ptg(x,val);return;
}
pd(x);
int m=(a[x].l+a[x].r)>>1;
if(l<=m) upd(lx,l,r,val);
if(r>m) upd(rx,l,r,val);
re(x);
}
il int que(int x,int p){
if(a[x].l==a[x].r) return a[x].s;
pd(x);
int m=(a[x].l+a[x].r)>>1;
if(p<=m) return que(lx,p);
else return que(rx,p);
}
struct line{
int h,xl,xr,v;
int l,r;
bool operator<(const line &a)const{
return h<a.h;
}
}b[N];
int dp[N];
int main(){
int n;
while(~scanf("%d",&n)){
int rmx=0;
mst(dp,0);
for(int i=1;i<=n;i++){
scanf("%d%d%d%d",&b[i].h,&b[i].xl,&b[i].xr,&b[i].v);
if(rmx<b[i].xr) rmx=b[i].xr;
}
sort(b+1,b+n+1);
bud(1,1,rmx);
for(int i=1;i<=n;i++){
b[i].l=que(1,b[i].xl);
b[i].r=que(1,b[i].xr);
upd(1,b[i].xl,b[i].xr,i);
}
dp[n]=100+b[n].v;
for(int i=n;i;i--){
if(dp[i]>0){
dp[b[i].l]=max(dp[b[i].l],dp[i]+b[b[i].l].v);
dp[b[i].r]=max(dp[b[i].r],dp[i]+b[b[i].r].v);
}
}
if(dp[0]<=0) dp[0]=-1;
printf("%d\\n",dp[0]);
}
return 0;
}
以上是关于Man Down(线段树dp)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 4521 小明系列问题——小明序列 (线段树维护DP)