萌新刚学splay 25pts 求条
查看原帖
萌新刚学splay 25pts 求条
936183
_zSqr_Mahiro_Oyama_楼主2024/9/7 17:15

rt,昨天调到23点15pts,今天又调了一会调到25pts调不下去了qwq

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int tot,root;
int son[N][2],fa[N];
int val[N],cnt[N],size[N];
long long sum[N];
//sum子树内权值和

int n,k;
int a[N],l,r,t;
long long ans=0x3f3f3f3f3f3f3f3f;

void update(int x){
	size[x]=size[son[x][0]]+size[son[x][1]]+cnt[x];
	sum[x]=sum[son[x][0]]+sum[son[x][1]]+1ll*val[x]*cnt[x];
}
int get(int x){
	return x==son[fa[x]][1];
}
void clear(int x){
	son[x][0]=son[x][1]=fa[x]=val[x]=cnt[x]=size[x]=sum[x]=0;
}

void rotate(int x){//上旋
	int y=fa[x],z=fa[y],k=get(x);
	son[y][k]=son[x][k^1];
	if(son[x][k^1])
		fa[son[x][k^1]]=y;
	son[x][k^1]=y;
	fa[y]=x;
	fa[x]=z;
	if(z)
		son[z][y==son[z][1]]=x;
	update(y);
	update(x);
}
void splay(int x){//伸展
	int y=fa[x];
	while(y){
		if(fa[y])
			rotate(get(x)==get(y)?y:x);
		rotate(x);
		y=fa[x];
	}
	root=x;
}
void insert(int v){//插入
	if(!root){
		tot++;
		val[tot]=v;
		cnt[tot]=1;
		root=tot;
		update(tot);
		return;
	}
	int cur=root,x=0;
	while(true){
		if(val[cur]==v){
			cnt[cur]++;
			update(cur);
			if(x)update(x);
			splay(cur);
			break;
		}
		x=cur;
		cur=son[cur][val[cur]<v];
		if(!cur){
			tot++;
			fa[tot]=x;
			son[x][val[x]<v]=tot;
			val[tot]=v;
			cnt[tot]=1;
			update(tot);
			update(x);
			splay(tot);
			break;
		}
	}
}
int get_rank(int v){//排名
	int ans=0,cur=root;
	while(cur){
		if(v<val[cur]){
			cur=son[cur][0];
		}else{
			ans+=size[son[cur][0]];
			if(val[cur]==v){
				splay(cur);
				return ans+1;
			}
			ans+=cnt[cur];
			cur=son[cur][1];
		}
	}
	return ans+1;
} 
int get_num(int rank){//用排名求数值
	int cur=root;
	while(true){
//		cout<<rank<<endl;
		if(son[cur][0]&&rank<=size[son[cur][0]]){
			cur=son[cur][0];
		}else{
			rank-=size[son[cur][0]]+cnt[cur];
			if(rank<=0){
				splay(cur);
				return val[cur];
			}
			cur=son[cur][1];
		}
	}
}
int pre(){//求根的前驱
	int cur=son[root][0];
	if(!cur)return root;
	while(son[cur][1])
		cur=son[cur][1];
	splay(cur);
	return cur;
}
void erase(int v){//删除
	get_rank(v);
	if(cnt[root]>1){
		cnt[root]--;
		update(root);
		return;
	}
	if(!son[root][0]&&!son[root][1]){
		clear(root);
		root=0;
		return;
	}
	if(!son[root][0]){
		int cur=root;
		root=son[root][1];
		fa[root]=0;
		clear(cur);
		return;
	}
	if(!son[root][1]){
		int cur=root;
		root=son[root][0];
		fa[root]=0;
		clear(cur);
		return;
	}
	int cur=root;
	int x=pre();
	fa[son[cur][1]]=x;
	son[x][1]=son[cur][1];
	clear(cur);
	update(root);
}
int main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	for(int i=1;i<=k;i++)
		insert(a[i]);
	for(int i=1;i<=n-k+1;i++){
//		cout<<i<<"*******\n";
//		for(int j=1;j<=k;j++)
//			cout<<get_num(j)<<' ';
//		cout<<endl;
		int x=get_num(k+1>>1);
		int ls=son[root][0],rs=son[root][1];
		if(ans>1ll*x*(cnt[ls]-cnt[rs])-sum[ls]+sum[rs]){
			ans=1ll*x*(cnt[ls]-cnt[rs])-sum[ls]+sum[rs];
			l=i;r=i+k-1;
			t=x;
		}
		if(i==n-k+1)continue; 
		erase(a[i]);
//		cout<<a[i]<<endl;
//		for(int j=1;j<=k-1;j++)
//			cout<<get_num(j)<<' ';
//		cout<<endl;
		insert(a[i+k]);
//		cout<<a[i+k]<<endl;
//		for(int j=1;j<=k;j++)
//			cout<<get_num(j)<<' ';
//		cout<<endl;
	}
	cout<<ans<<'\n';
	for(int i=1;i<=n;i++){
		if(l<=i&&i<=r)cout<<t;
		else cout<<a[i];
		cout<<'\n';
	}
	return 0;
}
2024/9/7 17:15
加载中...