QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#248709#7616. Jump Graphucup-team134#ML 0ms0kbC++144.9kb2023-11-11 21:03:132023-11-11 21:03:13

Judging History

你现在查看的是最新测评结果

  • [2023-11-11 21:03:13]
  • 评测
  • 测评结果:ML
  • 用时:0ms
  • 内存:0kb
  • [2023-11-11 21:03:13]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back

const int N=300050;
const int M=2*N;
struct SegTree{
	int val[M];
	function<int(int,int)> comb;
	int dflt;

	SegTree(function<int(int,int)> func, int _dflt){
		comb=func;
		dflt=_dflt;
		for(int i=0;i<M;i++)val[i]=dflt;
	}

	void Set(int i,int x){
		i+=N;
		val[i]=x;
		while(i>1){
			i>>=1;
			val[i]=comb(val[i<<1],val[i<<1|1]);
		}
	}

	int Get(int l,int r){
		l+=N;
		r+=N;
		int ans=dflt;
		while(l<=r){
			if(l%2==1){
				ans=comb(ans,val[l]);
				l++;
			}
			if(r%2==0){
				ans=comb(ans,val[r]);
				r--;
			}
			l/=2;
			r/=2;
		}
		return ans;
	}
};

const int inf=1e9+7;
SegTree SMX([](int x,int y){return max(x,y);}, -inf);

int p[N],where[N];
int ls[N],rs[N];
int ld[N],rd[N];
int n;
int Build(int l,int r,int LD=0,int RD=0){
	if(l>r)return 0;
	int m=where[SMX.Get(l,r)];
	ld[m]=LD;
	rd[m]=RD;
	ls[m]=Build(l,m-1,LD+1,RD);
	rs[m]=Build(m+1,r,LD,RD+1);
	return m;
}

const int H=4*20*N;
struct info{
	int cnt;
	ll sumL;
	ll sumR;

	info(){
		cnt=0;
		sumL=0;
		sumR=0;
	}
};

info operator + (const info& a,const info& b){
	info ans;
	ans.cnt=a.cnt+b.cnt;
	ans.sumL=a.sumL+b.sumL;
	ans.sumR=a.sumR+b.sumR;
	return ans;
}

namespace SegmentTree{
	int ls[H],rs[H],tsz;
	info sum[H];

	void Add(int&c,int ss,int se,int qi,int cnt,ll sumL,ll sumR){
		if(!c){
			c=++tsz;
			sum[c]=info();
		}
		if(ss==se){
			sum[c].cnt+=cnt;
			sum[c].sumL+=sumL;
			sum[c].sumR+=sumR;
			return;
		}
		int mid=ss+se>>1;
		if(qi<=mid)Add(ls[c],ss,mid,qi,cnt,sumL,sumR);
		else Add(rs[c],ss,mid,qi,cnt,sumL,sumR);
		sum[c]=sum[ls[c]]+sum[rs[c]];
	}

	info Get(int c,int ss,int se,int qs,int qe){
		if(qs>qe||qs>se||ss>qe)return info();
		if(qs<=ss&&qe>=se)return sum[c];
		int mid=ss+se>>1;
		return Get(ls[c],ss,mid,qs,qe)+Get(rs[c],mid+1,se,qs,qe);
	}

	void Merge(int&c,int l,int r,int ss,int se){
		if(!l || !r)c=l^r;
		else{
			c=++tsz;
			sum[c]=sum[l]+sum[r];
			int mid=ss+se>>1;
			Merge(ls[c],ls[l],ls[r],ss,mid);
			Merge(rs[c],rs[l],rs[r],mid+1,se);
		}
	}
};

int root[N];
ll ans[N],sub[N];
int Solve(int c,int l,int r){
	if(!c)return 0;

	int szl=c-l;
	int szr=r-c;


	int rtl=Solve(ls[c],l,c-1);
	int rtr=Solve(rs[c],c+1,r);


	if(szl){
		if(rd[c]==0){
			info linf=SegmentTree::Get(rtl,-N,N,-N,N);
			ans[c]+=linf.sumL-(ll)ld[c]*linf.cnt;
		}else{
			info linf=SegmentTree::Get(rtl,-N,N,-N,ld[c]-rd[c]+2);
			ans[c]+=linf.sumL-(ll)ld[c]*linf.cnt;
			info rinf=SegmentTree::Get(rtl,-N,N,ld[c]-rd[c]+3,N);
			ans[c]+=rinf.sumR-(ll)(rd[c]-2)*rinf.cnt;
		}

		if(szr){
			if(rd[c]==0){
				info linf=SegmentTree::Get(rtl,-N,N,-N,N);
				sub[rs[c]]+=linf.sumL-(ll)(ld[c]-1)*linf.cnt;
			}else{
				info linf=SegmentTree::Get(rtl,-N,N,-N,ld[c]-rd[c]+1);
				sub[rs[c]]+=linf.sumL-(ll)(ld[c]-1)*linf.cnt;
				info rinf=SegmentTree::Get(rtl,-N,N,ld[c]-rd[c]+2,N);
				sub[rs[c]]+=rinf.sumR-(ll)(rd[c]-2)*rinf.cnt;
			}
		}


		/*for(int i=l;i<c;i++){
			if(rd[c]==0 || (ld[i]-ld[c] < rd[i]-rd[c]+2)){
				ans[c]+=ld[i]-ld[c];
			}else{
				ans[c]+=rd[i]-rd[c]+2;
			}

			if(!szr)continue;
			if(rd[c]==0 || (ld[i]-ld[c]+1 < rd[i]-rd[c]+2)){
				sub[rs[c]]+=ld[i]-ld[c]+1;
			}else{
				sub[rs[c]]+=rd[i]-rd[c]+2;
			}
		}*/
		sub[ls[c]]++;
	}
	if(szr){
		if(ld[c]==0){
			info linf=SegmentTree::Get(rtr,-N,N,-N,N);
			ans[c]+=linf.sumR-(ll)rd[c]*linf.cnt;
		}else{
			info linf=SegmentTree::Get(rtr,-N,N,ld[c]-rd[c]-2,N);
			ans[c]+=linf.sumR-(ll)rd[c]*linf.cnt;
			info rinf=SegmentTree::Get(rtr,-N,N,-N,ld[c]-rd[c]-3);
			ans[c]+=rinf.sumL-(ll)(ld[c]-2)*rinf.cnt;
		}

		if(szl){
			if(ld[c]==0){
				info linf=SegmentTree::Get(rtr,-N,N,-N,N);
				sub[ls[c]]+=linf.sumR-(ll)(rd[c]-1)*linf.cnt;
			}else{
				info linf=SegmentTree::Get(rtr,-N,N,ld[c]-rd[c]-1,N);
				sub[ls[c]]+=linf.sumR-(ll)(rd[c]-1)*linf.cnt;
				info rinf=SegmentTree::Get(rtr,-N,N,-N,ld[c]-rd[c]-2);
				sub[ls[c]]+=rinf.sumL-(ll)(ld[c]-2)*rinf.cnt;
			}
		}

		/*for(int i=c+1;i<=r;i++){
			if(ld[c]==0 || (rd[i]-rd[c] < ld[i]-ld[c]+2)){
				ans[c]+=rd[i]-rd[c];
			}else{
				ans[c]+=ld[i]-ld[c]+2;
			}

			if(!szl)continue;
			if(ld[c]==0 || (rd[i]-rd[c]+1 < ld[i]-ld[c]+2)){
				sub[ls[c]]+=rd[i]-rd[c]+1;
			}else{
				sub[ls[c]]+=ld[i]-ld[c]+2;
			}
		}*/
		sub[rs[c]]++;
	}

	int root;
	SegmentTree::Merge(root,rtl,rtr,-N,N);
	SegmentTree::Add(root,-N,N,ld[c]-rd[c],1,ld[c],rd[c]);
	return root;
}

void Apply(int c){
	ans[c]+=sub[c];
	if(ls[c]){
		sub[ls[c]]+=sub[c];
		Apply(ls[c]);
	}
	if(rs[c]){
		sub[rs[c]]+=sub[c];
		Apply(rs[c]);
	}
}

int main(){
	scanf("%i",&n);
	for(int i=1;i<=n;i++){
		scanf("%i",&p[i]);
		where[p[i]]=i;
		SMX.Set(i,p[i]);
	}
	int root=Build(1,n);
	Solve(root,1,n);
	Apply(root);
	for(int i=1;i<=n;i++)printf("%lld ",ans[i]);
	printf("\n");
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Memory Limit Exceeded

input:

6
1 6 3 2 5 4

output:

11 7 7 7 6 8 

result: