ssoj2455有趣的有趣的家庭菜园(线段树)
2015-10-26 18:55
253 查看
【题意】有一个n块的线性菜园,每块菜园只有照到阳光(左右两边没有遮挡)才能收获果实卖出去价值为p,也可以除去费用为c,问最大利益是多少
【思路】枚举n块田地i为最高处,ans即为其左边最大利润加右边最大利润。dp o(n^2)会超时。用线段树维护左边(右边)最大值,点更新,与区间值的更改。
【代码】
【思路】枚举n块田地i为最高处,ans即为其左边最大利润加右边最大利润。dp o(n^2)会超时。用线段树维护左边(右边)最大值,点更新,与区间值的更改。
【代码】
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define ll long long using namespace std; const int maxn=100005; const ll inf=10000000000009; struct data{ ll mx,val; }tree[maxn*4]; ll n,h[maxn],H[maxn]; ll f[maxn],g[maxn],ans=0,p[maxn],c[maxn]; inline ll get(){ char c;while(!isdigit(c=getchar())); int v=c-48;while(isdigit(c=getchar()))v=v*10+c-48; return v; } inline void down(int node){ tree[node<<1].val+=tree[node].val; tree[(node<<1)+1].val+=tree[node].val; tree[node<<1].mx+=tree[node].val; tree[(node<<1)+1].mx+=tree[node].val; tree[node].val=0; } inline void mt(int node){ tree[node].mx=max(tree[node<<1].mx,tree[(node<<1)+1].mx); } inline void build(int node,int l,int r){ if(l==r){ if(l==0)tree[node].mx=0; else tree[node].mx=-inf; tree[node].val=0; } else{ int mid=(l+r)>>1; build(node<<1,l,mid); build((node<<1)+1,mid+1,r); mt(node); } } inline ll query(int node,int l,int r,int x,int y){ if(l>=x && r<=y)return tree[node].mx; else{ down(node); int mid=(l+r)>>1; if(y<=mid)return query(node<<1,l,mid,x,y); if(x>mid)return query((node<<1)+1,mid+1,r,x,y); return max(query(node<<1,l,mid,x,y),query((node<<1)+1,mid+1,r,x,y)); } } inline void add(int node,int l,int r,int p,ll x){ if(l==r)tree[node].mx=x; else{ down(node); int mid=(l+r)>>1; if(p<=mid)add(node<<1,l,mid,p,x); else add((node<<1)+1,mid+1,r,p,x); mt(node); } } inline void update(int node,int l,int r,int x,int y,ll v){ if(l>=x && r<=y)tree[node].val+=v,tree[node].mx+=v; else{ down(node); int mid=(l+r)>>1; if(x<=mid)update(node<<1,l,mid,x,y,v); if(y>mid)update((node<<1)+1,mid+1,r,x,y,v); mt(node); } } int main(){ n=get(); for(int i=1;i<=n;++i)H[i]=h[i]=get(),p[i]=get(),c[i]=get(); sort(H+1,H+1+n); int t=unique(H+1,H+1+n)-H-1; for(int i=1;i<=n;++i)h[i]=lower_bound(H+1,H+1+t,h[i])-H; build(1,0,n); for(int i=1;i<=n;++i){ f[i]=query(1,0,n,0,h[i])+p[i]; add(1,0,n,h[i],f[i]); update(1,0,n,0,h[i]-1,-c[i]); } memset(tree,0,sizeof(tree));build(1,0,n);//如果不memset貌似会出事 for(int i=n;i>=1;--i){ g[i]=query(1,0,n,0,h[i])+p[i]; add(1,0,n,h[i],g[i]); update(1,0,n,0,h[i]-1,-c[i]); } for(int i=1;i<=n;++i)ans=max(ans,f[i]+g[i]-p[i]); printf("%lld\n",ans); return 0; }
相关文章推荐
- HDOJ 2030 汉字统计
- Python的getattr(),setattr(),delattr(),hasattr()
- 大型项目使用Automake/Autoconf完成编译配置
- iOS Crash获取闪回日志和上传server
- HDOJ 2030 汉字统计
- No.10_分数分配
- 301跳转 PHP
- 牛客网:确定两串乱序同构
- c++学习笔记(十四):多态的综合运用——模拟发动报文
- Mavericks下如何安装Command Line Tools(命令行工具)
- php-验证码
- .NET C# Tostring() format 格式化字符串大全
- Jfinal中定时器的初步探索(二)
- JAVA 封装 继承 多态
- OC的基础_类
- docker简单教程
- jquery异步加载json格式的数据
- HDOJ 1312 (POJ 1979) Red and Black
- HDOJ 1312 (POJ 1979) Red and Black
- jquery异步加载json格式的数据