样例过不去!!!
查看原帖
样例过不去!!!
142549
hbhz_zcy楼主2022/5/5 12:06

我看着题解写的(不太懂,知道原理,不会写),觉得题解的代码实现不是很丝滑,改了一些地方(例如ans直接统计、初始情况为0的情况),但是发现过不了。

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int maxn=2e4+10,maxh=(1<<30)-1;
int N,M,pos[maxn],v1[maxn],len[maxn],v2[maxn],dp[maxn],pl[maxn],pr[maxn],ans=maxh;
vector<int>vec[maxn];
vector<int>::iterator it;
struct node{int l,r,v,lazy;}f[maxn<<3];
void pushup(int t){f[t].v=min(f[t<<1].v,f[t<<1|1].v);}
void pushdown(int t){
	int l=f[t].l,r=f[t].r;
	f[l].v+=f[t].lazy,f[r].v+=f[t].lazy;
	f[l].lazy+=f[t].lazy,f[r].lazy+=f[t].lazy;
	f[t].lazy=0;
}
void build(int t,int l,int r){
	f[t].l=l,f[t].r=r,f[t].lazy=0;
	if(l==r){f[t].v=dp[l];return;}
	int m=(l+r)>>1;
	build(t<<1,l,m),build(t<<1|1,m+1,r);
	pushup(t);
}
void change(int t,int ul,int ur,int x){
	int l=f[t].l,r=f[t].r;
	if(ul<=l&&r<=ur){f[t].v+=x;return;}
	pushdown(t);int m=(l+r)>>1;
	if(ul<=m)  change(t<<1,ul,ur,x);
	if(m<ur)  change(t<<1|1,ul,ur,x);
	pushup(t);
}
int ask(int t,int ul,int ur){
	int l=f[t].l,r=f[t].r;
	if(ul<=l&&r<=ur)  return f[t].v;
	pushdown(t);int m=(l+r)>>1,rt=maxh;
	if(ul<=m)  rt=min(rt,ask(t<<1,ul,ur));
	if(m<ur)  rt=min(rt,ask(t<<1|1,ul,ur));
	return rt;
}
int qd(){
	int rt=0;char c=getchar();
	while(c<'0'||c>'9')  c=getchar();
	while('0'<=c&&c<='9')  rt=(rt<<3)+(rt<<1)+c-48,c=getchar();
	return rt;
}
int main(){
	N=qd(),M=qd();
	for(int i=2;i<=N;i++)  pos[i]=qd();
	for(int i=1;i<=N;i++)  v1[i]=qd();
	for(int i=1;i<=N;i++)  len[i]=qd();
	for(int i=1;i<=N;i++)  v2[i]=qd(),dp[i]=dp[i-1]+v2[i];
	for(int i=1;i<=N;i++){//a point ex to right and left most
		pl[i]=lower_bound(pos+1,pos+N+1,pos[i]-len[i])-pos;
		pr[i]=lower_bound(pos+1,pos+N+1,pos[i]+len[i])-pos;
		if(pos[pr[i]]>pos[i]+len[i])  pr[i]--;
		vec[pr[i]].push_back(i);
	}
//	for(int i=1;i<=N;i++){
//		printf("%d:at %d  len %d  l %d  r %d\n",i,pos[i],len[i],pl[i],pr[i]);
//	}
//	int sum=0;
//	for(int i=1;i<=N;i++){
//		dp[i]=sum+v1[i];
//		for(it=vec[i].begin();it!=vec[i].end();it++)  sum+=v2[*it];
//	}
	ans=dp[N];
	for(int i=1;i<=M;i++){
		build(1,1,N);
		for(int j=1;j<=N;j++){
			dp[j]=ask(1,1,j-1)+v1[j];
//			printf("dp %d=%d\n",j,dp[j]);
			for(it=vec[j].begin();it!=vec[j].end();it++){
				int k=*it;
				change(1,1,pl[k]-1,v2[k]);
//				printf("change %d %d\n",pl[k]-1,v2[k]);
			}
		}
//		printf("f[1].v=%d\n",f[1].v);
		ans=min(ans,f[1].v);
	}
	printf("%d\n",ans);
	return 0;
}
2022/5/5 12:06
加载中...