66pts,WA+MLE求助
查看原帖
66pts,WA+MLE求助
989792
lrx___楼主2025/1/23 22:02
#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
#define debug(...) fprintf(stderr,__VA_ARGS__)
#else
#define debug(...)
#endif
using namespace std;
using namespace chrono;
typedef signed char i8;typedef short i16;typedef int i32;typedef long long i64;typedef unsigned char u8;typedef unsigned short u16;typedef unsigned u32;typedef unsigned long long u64;typedef float f32;typedef double f64;typedef long double f96;

constexpr int N(4e5+5);
int n,rt,val[N],ls[N],rs[N];
i64 ans,sum;
struct node{
	int sum;
	node *ls,*rs;
}t[N<<2],*root[N];

namespace segment_tree{
	void update(int x,node*& u,int l=1,int r=n){
		if(!u){
			u=new node;
			u->ls=u->rs=nullptr;
			u->sum=0;
		}
		++u->sum;
		if(l==r){
			return;
		}
		const int mid{(l+r)>>1};
		x<=mid?update(x,u->ls,l,mid):update(x,u->rs,mid+1,r);
	}
	int query(int x,int y,node*& u,int l=1,int r=n){
		if(!u||r<x||y<l||y<x){
			return 0;
		}
		if(x<=l&&r<=y){
			return u->sum;
		}
		const int mid{(l+r)>>1};
		return query(x,y,u->ls,l,mid)+query(x,y,u->rs,mid+1,r);
	}
	void merge_tree(node*& u,node*& v,int l=1,int r=n){
		if(!v){
			return;
		}
		if(!u){
			u=v;v=nullptr;return;
		}
		u->sum+=v->sum;
		const int mid{(l+r)>>1};
		merge_tree(u->ls,v->ls,l,mid);
		merge_tree(u->rs,v->rs,mid+1,r);
		delete v;v=nullptr;
	}
	void travel(node*& u,node*& other_root,int l=1,int r=n){
		if(!u){
			return;
		}
		if(l==r){
			sum+=query(1,l-1,other_root);
			return;
		}
		const int mid{(l+r)>>1};
		travel(u->ls,other_root,l,mid);
		travel(u->rs,other_root,mid+1,r);
	}
	void recycle(node*& u){
		if(u){
			recycle(u->ls);
			recycle(u->rs);
			delete u;
		}
	}
}
void read(int& u){
	u=++n;
	scanf("%d",val+u);
	if(val[u]){
		return;
	}else{
		read(ls[u]);
		read(rs[u]);
	}
}
void dfs(int u){
	if(val[u]){
		segment_tree::update(val[u],root[u]);
		return;
	}
	dfs(ls[u]);
	dfs(rs[u]);
	if(root[ls[u]]->sum<root[rs[u]]->sum){
		swap(ls[u],rs[u]);
	}
	sum=0;
	segment_tree::travel(root[rs[u]],root[ls[u]]);
	ans+=min(sum,(i64)(root[ls[u]]->sum)*root[rs[u]]->sum-sum);
	segment_tree::merge_tree(root[u],root[ls[u]]);
	segment_tree::merge_tree(root[u],root[rs[u]]);
}
int main(){
	scanf("%d",&n);
	read(rt);
	dfs(rt);
	printf("%lld\n",ans);
	segment_tree::recycle(root[1]);
	return 0;
}

2025/1/23 22:02
加载中...