求助,线段树出bug了
查看原帖
求助,线段树出bug了
305891
夜明楼主2021/10/31 11:29
#include<iostream>
#include<cstdio>
using namespace std;
const int Maxn=2*1e9;
int dis[20005],cst[20005],rg[20005],wst[20005],dp[20005],st[20005],ed[20005];
struct segTree{
	int l,r;
	int lz;
	int minn;
}tree[80005];
int num[20005];
struct node{
	int end;
	int nxt;
	int id;
	void add(int u,int v,int w){
		end=v;
		nxt=num[u];
		num[u]=w;
		id=w;
	}
}Edge[20005];
int binarySearch_min(int n,int x){
	int l=1,r=n,ans=0;
	while(l<=r){
		int mid=(l+r)/2;
		if(dis[mid]<x)
			l=mid+1,ans=mid;
		else
			r=mid-1;
	}
	return ans;
}
int binarySearch_max(int n,int x){
	int l=1,r=n,ans=n+1;
	while(l<=r){
		int mid=(l+r)/2;
		if(dis[mid]>x)
			r=mid-1,ans=mid;
		else
			l=mid+1;
	}
	return ans;
}
void Init(int n){
	for(int i=1;i<=n;i++)
		dp[i]=dp[i-1]+wst[i];
	for(int i=1;i<=n;i++)
		st[i]=binarySearch_min(n,dis[i]-rg[i]);
	for(int i=1;i<=n;i++)
		ed[i]=binarySearch_max(n,dis[i]+rg[i]);
	for(int i=1;i<=n;i++)
		Edge[i].add(ed[i],st[i],i);
}
void Build(int k,int l,int r){
	tree[k].l=l;
	tree[k].r=r;
	if(l==r){
		tree[k].minn=dp[l];
		return;
	}
	int mid,lc,rc;
	mid=(l+r)/2;
	lc=2*k,rc=2*k+1;
	Build(lc,l,mid);
	Build(rc,mid+1,r);
	tree[k].minn=min(tree[lc].minn,tree[rc].minn);
}
void Lazy(int k,int v){
	tree[k].minn+=v;
	tree[k].lz+=v; 
}
void Pushdown(int k){
	int v=tree[k].lz;
	Lazy(2*k,v);
	Lazy(2*k+1,v);
	tree[k].lz=0;
}
void Pushup(int k){
	int lc,rc;
	lc=2*k,rc=2*k+1;
	tree[k].minn=min(tree[lc].minn,tree[rc].minn);
}
void Update(int k,int l,int r,int v){
	if(l<=tree[k].l&&r>=tree[k].r)
		return Lazy(k,v);
	Pushdown(k);
	int mid,lc,rc;
	mid=(tree[k].l+tree[k].r)/2;
	lc=2*k,rc=2*k+1;
	if(l<=mid)
		Update(lc,l,r,v);
	if(r>mid)
		Update(rc,l,r,v);
	Pushup(k);
}
int Query(int k,int l,int r){
	if(l<=tree[k].l&&r>=tree[k].r)
		return tree[k].minn;
	int mid,lc,rc,ans=Maxn;
	mid=(tree[k].l+tree[k].r)/2;
	lc=2*k,rc=2*k+1;
	if(l<=mid)
		ans=min(ans,Query(lc,l,r));
	if(r>mid)
		ans=min(ans,Query(rc,l,r));
	return ans;
}
void Read(int n,int k){
	for(int i=2;i<=n;i++)
		scanf("%d",&dis[i]);
	for(int i=1;i<=n;i++)
		scanf("%d",&cst[i]);
	for(int i=1;i<=n;i++)
		scanf("%d",&rg[i]);
	for(int i=1;i<=n;i++)
		scanf("%d",&wst[i]);
}
int Solve(int n,int k){
	int ans=dp[n]; 
	for(int i=1;i<=k;i++){
		Build(1,1,n);
		for(int j=1;j<=n;j++){
			for(int h=num[j];h;h=Edge[h].nxt){
				int y=Edge[h].end;
				int id=Edge[h].id;
				if(y>0)
					Update(1,1,y,wst[id]);
			}
			if(j>i)
				dp[j]=min(Query(1,1,j)+cst[j],dp[j]);
			else
				dp[j]=min(dp[j],cst[j]);
		}
		ans=min(ans,dp[n]);
	}
	return ans;
}
int main(){
	int n,k;
	scanf("%d%d",&n,&k);
	Read(n,k);
	Init(n);
	printf("%d\n",Solve(n,k));
	return 0;
}
2021/10/31 11:29
加载中...