线段树+dp爆0求助,壶关
查看原帖
线段树+dp爆0求助,壶关
684285
Makerlike楼主2023/12/16 10:01

就爆零了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define int long long
const int N=1e5+10;
const int INF=0x3f3f3f3f3f3f3f3f;
int n,k;
int dis[N],c[N],s[N],w[N],dp[N];
int End[N],Start[N];
//图
struct Edge{
	int to;
	int nxt;
}edge[N<<2];
int head[N],tot=-1;
void init(){
	memset(head,-1,sizeof(head));
	tot=-1;
}
void add(int x,int y){
	edge[++tot].to=y;
	edge[tot].nxt=head[x];
	head[x]=tot;
}
//线段树 
struct Tree{
	int left;
	int right;
	int minn;
	int lazy;
}tree[N<<2];
#define L(root) tree[root].left
#define R(root) tree[root].right
#define M(root) tree[root].minn
#define T(root) tree[root].lazy
#define lson root<<1
#define rson root<<1|1
void pushup(int root){
	M(root)=min(M(lson),M(rson));
}
void pushdown(int root){
	if(T(root)!=0){
		M(lson)+=T(root);
		M(rson)+=T(root);
		T(lson)+=T(root);
		T(rson)+=T(root);
		T(root)=0;
	}
}
void build(int root,int l,int r){
	L(root)=l;
	R(root)=r;
	T(root)=0;
	if(l==r){
		M(root)=dp[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(lson,l,mid);
	build(rson,mid+1,r);
	pushup(root);
}
void update(int root,int l,int r,int tmp){
	if(l>r)
		return;
	if(l<=L(root)&&r>=R(root)){
		M(root)+=tmp;
		T(root)+=tmp;
		return;
	}
	pushdown(root);
	int mid=(L(root)+R(root))>>1;
	if(l<=mid)
		update(lson,l,r,k);
	if(r>mid)
		update(rson,l,r,k);
	pushup(root);
}
int query(int root,int l,int r){
	if(l>r)
		return 0;
	if(l<=L(root)&&r>=R(root)){
		return M(root);
	}
	pushdown(root);
	int mid=(L(root)+R(root))>>1;
	int ans=INF;
	if(l<=mid)
		ans=min(ans,query(lson,l,r));
	if(r>mid)
		ans=min(ans,query(rson,l,r));
	return ans;
}


signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	init();
	cin>>n>>k;
	for(int i=2;i<=n;i++)
		cin>>dis[i];
	for(int i=1;i<=n;i++)
		cin>>c[i]; //val
	for(int i=1;i<=n;i++)
		cin>>s[i]; //range
	for(int i=1;i<=n;i++)
		cin>>w[i]; //pay
	++n;
	++k;
	dis[n]=w[n]=INF;
	for(int i=1;i<=n;i++){
		Start[i]=lower_bound(dis+1,dis+1+n,dis[i]-s[i])-dis;
		End[i]=lower_bound(dis+1,dis+1+n,dis[i]+s[i])-dis;
		if(dis[End[i]]>dis[i]+s[i])
			End[i]--;
		add(End[i],i);
	}
	int now=0;
	for(int i=1;i<=n;i++){
		dp[i]=now+c[i];
		for(int j=head[i];~j;j=edge[j].nxt){
			int v=edge[j].to;
			now+=w[v];
		}
	}
	int ans=dp[n];
	for(int i=2;i<=k;i++){
		build(1,1,n);
		for(int j=1;j<=n;j++){
			dp[j]=query(1,1,j-1)+c[j];
			for(int p=head[j];~p;p=edge[p].nxt){
				int v=edge[p].to;
				update(1,1,Start[v]-1,w[v]);
			}
		}
		ans=min(ans,dp[n]);
	}
	cout<<ans;
	return 0;
} 
2023/12/16 10:01
加载中...