bzoj 2131: 免费的馅饼

易得方程 $f[i]=max(f[j])+v[i]$,条件是 $t[i]<t[j]$ 且 $2t[j]-x[j]<=2t[i]-x[i]$ 且 $2t[j]+x[j]<=2t[i]+x[i]$ 

一共有 3 个条件,但是你发现如果满足后面两个条件,自然满足第一个条件. 

所以可以将问题转化为一个二位偏序问题,离线+树状数组处理一下即可. 

code: 

#include <bits/stdc++.h>    
#define N 100007 
#define LL long long   
using namespace std;    
void setIO(string s) 
{
    string in=s+".in";  
    string out=s+".out"; 
    freopen(in.c_str(),"r",stdin);  
    // freopen(out.c_str(),"w",stdout); 
} 
struct data 
{ 
    int t,x,v,key1,key2;   
}a[N];         
bool cmp(data a,data b) 
{
    return a.key1<b.key1;  
}
int C[N],A[N],f[N];     
int lowbit(int t) { return t&(-t); } 
void update(int x,int v) 
{
    for(;x<N;x+=lowbit(x)) C[x]=max(C[x],v);   
}
int query(int x) 
{
    int ans=0; 
    for(;x;x-=lowbit(x))    ans=max(ans, C[x]);   
    return ans;    
}
int main() 
{
    // setIO("input");         
    int w,n,i,j,ans=0; 
    scanf("%d%d",&w,&n); 
    for(i=1;i<=n;++i)
    {
        scanf("%d%d%d",&a[i].t,&a[i].x,&a[i].v);                    
        a[i].key1=2*a[i].t-a[i].x; 
        a[i].key2=2*a[i].t+a[i].x; 
        A[i]=a[i].key2; 
    }
    sort(A+1,A+1+n); 
    for(i=1;i<=n;++i)  a[i].key2=lower_bound(A+1,A+1+n,a[i].key2)-A; 
    sort(a+1,a+1+n,cmp);    
    for(i=1;i<=n;++i) 
    {
        f[i]=query(a[i].key2)+a[i].v;     
        update(a[i].key2,f[i]);   
        ans=max(ans,f[i]); 
    }
    printf("%d
",ans); 
    return 0; 
}

  

原文地址:https://www.cnblogs.com/guangheli/p/11782247.html