+思考セグメントツリーのセールスマン(ロス・バレーP2672)

セールスマン

タイトル説明

アミンはセールスマンだった、彼は自分の会社の製品を販売する通りネジを命じられました。スクリュー通りが行き止まりであり、出口と入口は反対側には家庭である、通りの同一の、壁側です。ねじN通りの総世帯は、i番目メートルの入り口からのテナントは、Siです。同じ家は、テナントの数を持つことができるので、そう入口から世帯の等しい数が存在してもよいです。アミンは、Xファミリー世帯の通りネジに自社製品を促進するために、入り口から入り、その後、同じように出て行くだろう。
Aminのすべての1メートルは、i番目の世帯に疲労愛小数点値を蓄積する自社製品を促進するため、午前1時疲労値を蓄積します。Aminさんは仕事中毒である、彼は不必要な移動するための方法、およびどのように多くのポイント彼が最も疲労値を蓄積せずに、異なるXのために、知りたいと思いました。

入力形式

最初の行は、正の整数N、家庭通りネジの数を有しています。

Siはi番目のエントリへの家庭から第i番目の整数を表し、nは正の整数の次の行、。a_iを整数疲労は、i番目の家庭に蓄積し促進するための製品のi番目の値を表すデータ保証S_1≤S_2≤...≤S_n<N 10 ^ 8次の行の正の整数、。データ保証a_iを<1000年

出力フォーマット

N本の出力線は、それぞれ正の整数であり、X = iは、アミンが最も蓄積i行目の疲労整数値。


セグメントツリーのメンテナンス間隔の最大値;,

ユーザMXL家庭の最大距離を記録する前にI-1と、第1のユーザの距離が少ない最大値Iよりも、その後ノーオペレーション、
最大値よりも大きい場合、I mxl-ユーザの値は、家庭の疲労値となり、ユーザへのIのN + 1番目のユーザマイナスi番目のユーザの距離MXLにユーザ。

コード:

#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define ls k<<1
#define rs k<<1|1
#define inf 0x3f3f3f3f
using namespace std;
const int N=100010;
const int M=2000100;
const LL mod=2e9;
int n,s[N],a[N];
struct Node{
	int l,r,num;
	LL mx,lt;
}tr[N*4];
void pp(int k){
	if(tr[ls].mx>=tr[rs].mx) tr[k].mx=tr[ls].mx,tr[k].num=tr[ls].num;
	else tr[k].mx=tr[rs].mx,tr[k].num=tr[rs].num;
}
void pd(int k){
	if(tr[k].lt){
		tr[ls].mx-=tr[k].lt;
		tr[rs].mx-=tr[k].lt;
		tr[ls].lt+=tr[k].lt;
		tr[rs].lt+=tr[k].lt;
	}
	tr[k].lt=0;
}
void build(int l,int r,int k){
	tr[k].l=l,tr[k].r=r;
	if(l==r){
		tr[k].mx=(LL)(2*s[l]+a[l]);
		tr[k].num=l;
		return;
	}
	int d=(l+r)>>1;
	build(l,d,ls);
	build(d+1,r,rs);
	pp(k);
}
void update1(int l,int r,int k){
	if(tr[k].mx<=0||l>r) return;
	if(tr[k].l==tr[k].r){
		tr[k].mx=a[tr[k].num];
		return;
	}
	pd(k);
	int d=(tr[k].l+tr[k].r)>>1;
	if(l<=d) update1(l,r,ls);
	if(r>d) update1(l,r,rs);
	pp(k);
}
void update2(int l,int r,LL w,int k){
	if(tr[k].mx<=0||l>r) return;
	if(tr[k].l>=l&&tr[k].r<=r){
		tr[k].mx-=w;
		tr[k].lt+=w;
		return;
	}
	pd(k);
	int d=(tr[k].l+tr[k].r)>>1;
	if(l<=d) update2(l,r,w,ls);
	if(r>d) update2(l,r,w,rs);
	pp(k);
}
void dele(int pos,int k){
	if(tr[k].l==tr[k].r){
		tr[k].mx=0;
		return;
	}
	pd(k);
	int d=(tr[k].l+tr[k].r)>>1;
	if(pos<=d) dele(pos,ls);
	else dele(pos,rs);
	pp(k);
}
int main(){
	cin>>n;
	for(int i=1;i<=n;i++) scanf("%d",&s[i]);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	build(1,n,1);
	LL ans=0;
	int mxl=0;
	for(int i=1;i<=n;i++){
		ans+=tr[1].mx;
		int k=tr[1].num;
		if(k>mxl){
			update1(mxl+1,k-1,1);
			update2(k+1,n,2ll*(s[k]-s[mxl]),1);
			mxl=k;
		}
		printf("%d\n",ans);
		dele(k,1);
	}
	return 0;
}
公開された264元の記事 ウォン称賛46 ビュー10000 +

おすすめ

転載: blog.csdn.net/qq_44291254/article/details/105268728