原题
蒟蒻过掉了本题,但感觉并没有完全理解...
题解的做法大同小异,根据 i 从 j 合法转移要求的条件:
2∗ti+pi<=2∗tj+pj(pi<=pj)
2∗ti−pi<=2∗tj−pj(pi>pj)
然后按照第一个式子关键字排序,对第二个式子对应的关键字离散化后利用树状数组优化进行转移(类似于顺序对的方法)
然鹅蒟蒻我推到上面那两个个式子就蚌住了qwq
上面那两个式子得以成立的前提似乎是:
ti>=tj
这是推导过程中默认的条件,不然t也得套绝对值进行讨论了
但是按照上面第一个关键字排序后,似乎不能保证t_i>=t_j了
举个例子,t1=5,p1=1,t2=6,p2=2
两个关键字比完1都比2小
按本算法也就是1可以从2转移过来
但显然时间t1<t2,时间不可能倒流这个转移时非法的
但这个数据卡不掉,因为实际上应该是2从1转移过来,结果是一样的
以本做法能AC来看,这种做法尽管转移的意义可能会与实际不同,但结果应该都是没问题的
但我还是对这道题的不用讨论t先后的原因不很理解
希望各位大佬能指点一下本题是如何避免对t的绝对值的讨论的
谢谢!OvO
(附迷惑之下写出的AC代码)
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+100;
#define ll long long
#define I register int
ll read(){
ll x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
int n;
struct node{
int pl,t,v;
bool operator < (const node y)const{return 2*t+pl<2*y.t+y.pl;}
}p[N];
int q[N],cnt;
int f[N];
void add(int x,int v){
for(;x<=cnt;x+=x&-x) f[x]=max(f[x],v);
}
int ask(int x){
int res=0;
for(;x;x-=x&-x) res=max(res,f[x]);
return res;
}
int main(){
int w=read();n=read();
for(int i=1;i<=n;i++){
p[i].t=read();p[i].pl=read();p[i].v=read();
q[i]=2*p[i].t-p[i].pl;
}
sort(p+1,p+1+n);
sort(q+1,q+1+n);
cnt=unique(q+1,q+1+n)-q-1;
for(int i=1;i<=n;i++){
int o=lower_bound(q+1,q+1+cnt,2*p[i].t-p[i].pl)-q;
add(o,ask(o-1)+p[i].v);
}
printf("%d",ask(cnt));
}
/*
*/