只得到了高贵的8pts
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 100010
#define lowbit(x) x&(-x)
int c,T;
int n,m,K,d,x,y,v[N];
int X[N],Y[N];//此处X,Y分别记录每个任务区间的左右端点
int b[N],cnt;//离散化数组
struct que{
int y,v;
};
vector<que> q[N];
int dp[N];
/*树状数组*/
int Bit[N];
void add(int x,int k){
while(x<=cnt){Bit[x]+=k; x+=lowbit(x);}
}
int get(int x){
int res=0;
while(x>0){res+=Bit[x]; x-=lowbit(x);}
return res;
}
int ask(int l,int r){return get(r)-get(l-1);}
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>c>>T;
while(T--){
for(int i=1;i<=cnt;i++) {
q[i].clear();Bit[i]=0;dp[i]=0;b[i]=0;v[i]=0;X[i]=Y[i]=0;}
cnt=0;
cin>>n>>m>>K>>d;
for(int i=1;i<=m;i++){
cin>>x>>y>>v[i];
X[i]=x-y+1; Y[i]=x;
b[++cnt]=x;
b[++cnt]=x-y+1;
}
//离散化
sort(b+1,b+cnt+1);
cnt=unique(b+1,b+cnt+1)-b-1;
for(int i=1;i<=m;i++){
X[i]=lower_bound(b+1,b+cnt+1,X[i])-b;
Y[i]=lower_bound(b+1,b+cnt+1,Y[i])-b;
q[Y[i]].push_back((que){X[i],v[i]});
}
/*暴力dp*/
dp[0]=0;
for(int i=1;i<=cnt;i++){//枚举天数
//把枚举到的挑战加入树状数组,便于查询
for(auto it:q[i]){
add(it.y,it.v);
}
for(int j=i;j>=1&&(b[i]-b[j]+1<=K);j--){
//枚举j代表从j到i这段时间跑步。
/*转移从j-2来,因为连续跑步天数不超过K,所以我们枚举到j则第
j-1天一定不跑(否则将存在一个长度大于K的大区间)则从j-2转移
注意离散化之后需要注意相邻两个值是否相差1,差1则选取j-2,否则
直接选取j-1*/
int pos=(b[j-1]!=b[j]-1)?j-1:j-2;
int tmp=(pos<=0)?0:dp[pos];
//j-2可能越界,但越界了也能转移,所以需要特殊处理
dp[i]=max(dp[i],tmp+ask(j,i)-d*(i-j+1));
}
dp[i]=max(dp[i],dp[i-1]);//今天不跑,直接继承
}
cout<<dp[cnt]<<'\n';
}
return 0;
}