思路就是直接用slope trick维护1e9的dp数组
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,q,p[10010],a[10010],b[10010],pl;
struct node{
int l,val,k;
bool operator <(const node o)const{
return l<o.l;
}
};
set<node> st;
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld %lld %lld",&p[i],&a[i],&b[i]);
}
st.insert({0,0,1});
for(int i=n;i>=1;i--){
// for(auto aa=st.begin();aa!=st.end();aa++){
// printf("aggggggggggggggg %lld %lld %lld\n",aa->l,aa->val,aa->k);
// }
set<node> tmp;
tmp.clear();
auto itt=st.upper_bound({a[i]-pl,0,0});
itt--;
while(itt!=st.end()&&itt->l+pl<=p[i]+a[i]){
tmp.insert({max(itt->l-a[i]-b[i],-pl-b[i]),itt->val+(max(itt->l-a[i]-b[i],-pl-b[i])-itt->l+a[i]+b[i])*itt->k,itt->k});
// printf("tmp insert %lld %lld %lld\n",max(itt->l-a[i]-b[i],-pl-b[i]),itt->val+(max(itt->l-a[i]-b[i],-pl-b[i])-itt->l+a[i]+b[i])*itt->k,itt->k);
itt++;
}
// printf("pl -> %lld\n",pl+b[i]);
if(p[i]<b[i]){
auto aaa=*st.lower_bound({-pl,0,0});
pl+=b[i];
st.insert({p[i]-pl+1,aaa.val,0});
}
else{
pl+=b[i];
auto it=st.upper_bound({p[i]-pl+1,0,0});
// printf("bbbbbbbb %lld %lld %lld\n",it->l,it->val,it->k);
it--;
if(it->l!=p[i]-pl+1){
auto tt=(*it);
// printf("aaaaaaaaaaaaaaa%lld %lld %lld %lld\n",tt.l,p[i]-pl+1,it->val,tt.k);
st.erase(it);
tt.val+=(p[i]-pl+1-tt.l)*tt.k;
tt.l=p[i]-pl+1;
st.insert(tt);
// printf("insert %lld %lld %lld\n",tt.l,tt.val,tt.k);
}
// printf("clear < %lld\n",p[i]-pl+1);
it=st.lower_bound({p[i]-pl+1,0,0});
while(it!=st.begin()){
it--;
st.erase(it);
it=st.lower_bound({p[i]-pl+1,0,0});
}
}
for(auto ii=tmp.begin();ii!=tmp.end();ii++){
st.insert(*ii);
}
}
scanf("%lld",&q);
for(int i=1;i<=q;i++){
int x;
scanf("%lld",&x);
auto it=st.upper_bound({x-pl,0,0});
it--;
printf("%lld\n",it->val+(x-pl-it->l)*it->k);
}
return 0;
}