QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#248709 | #7616. Jump Graph | ucup-team134# | ML | 0ms | 0kb | C++14 | 4.9kb | 2023-11-11 21:03:13 | 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