1 /* 2 题意:n天,第i天可以获得的值为vi,如果获得第i天的值,那么下一次能获得的值 3 只能在[i+x[i],i+y[i]-1]天中取,为最大能获得多少值; 4 5 分析:直接DP,每次维护经过前i-1天第i天能可以获得的最大值,用线段树维护就要同时记录下区间的最大最小值; 6 表示区间内的可能获得最大值的最大值和最小值; 7 另一种DP的思路,dp[i]表示选了第i天,最终能获得的最大值,那么dp[i]=v[i]+max(dp[i+x[i]],dp[i+y[i]-1]); 8 直接用线段树维护区间最大值就可以了; 9 10 */ 11 #include<cstdio> 12 #include<cstring> 13 #include<cstdlib> 14 #include<iostream> 15 #include<cmath> 16 #include<algorithm> 17 #define lson l,m,rt<<1 18 #define rson m+1,r,rt<<1|1 19 using namespace std; 20 const int N=50000+10; 21 int maxv[N<<2],minv[N<<2],col[N<<2]; 22 int x[N],y[N],v[N]; 23 int n; 24 void pushup(int rt){ 25 maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]); 26 minv[rt]=min(minv[rt<<1],minv[rt<<1|1]); 27 } 28 void build(int l,int r,int rt){ 29 maxv[rt]=minv[rt]=col[rt]=0; 30 if (l==r) return ; 31 int m=(l+r)>>1; 32 build(lson);build(rson); 33 } 34 void pushdown(int rt){ 35 if (col[rt]){ 36 if (col[rt]>=maxv[rt<<1]){ 37 maxv[rt<<1]=minv[rt<<1]=col[rt]; 38 }else if (col[rt]>minv[rt<<1])minv[rt<<1]=col[rt]; 39 col[rt<<1]=max(col[rt<<1],col[rt]); 40 41 if (col[rt]>=maxv[rt<<1|1]){ 42 maxv[rt<<1|1]=minv[rt<<1|1]=col[rt]; 43 }else if (col[rt]>minv[rt<<1|1])minv[rt<<1|1]=col[rt]; 44 col[rt<<1|1]=max(col[rt<<1|1],col[rt]); 45 46 col[rt]=0; 47 } 48 } 49 void update(int L,int R,int v,int l,int r,int rt){ 50 if (v<=minv[rt]) return; 51 if (L<=l && r<=R){ 52 if (v>=maxv[rt]){ 53 maxv[rt]=minv[rt]=v; 54 }else if (v>minv[rt]){ 55 minv[rt]=v; 56 } 57 col[rt]=max(col[rt],v); 58 return; 59 } 60 int m=(l+r)>>1; 61 pushdown(rt); 62 if (L<=m) update(L,R,v,lson); 63 if (m< R) update(L,R,v,rson); 64 pushup(rt); 65 } 66 int query(int L,int l,int r,int rt){ 67 if (l==r){ 68 return maxv[rt]; 69 } 70 int m=(l+r)>>1; 71 pushdown(rt); 72 if(L<=m) return query(L,lson); 73 else return query(L,rson); 74 } 75 int main(){ 76 while (~scanf("%d",&n)){ 77 for (int i=1;i<=n;i++){ 78 scanf("%d%d%d",&v[i],&x[i],&y[i]); 79 } 80 build(1,n+1,1); 81 int ret=0; 82 for (int i=1;i<=n;i++){ 83 int t=query(i,1,n+1,1); 84 if (i!=1 && t==0) continue; 85 t+=v[i]; 86 // cout<<i<<" "<<t<<endl; 87 if (t>ret) ret=t; 88 int l=min(n+1,i+x[i]),r=min(n+1,i+y[i]-1); 89 update(l,r,t,1,n+1,1); 90 } 91 printf("%d\n",ret); 92 } 93 94 return 0; 95 }