玄关,25pts求挑splay
查看原帖
玄关,25pts求挑splay
469470
EurekaStriker楼主2023/11/9 20:21

tnnd,我2263都卡常过了,你凭什么不给我过!!!

事WA不事TLE

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN=2000010;
int n,son[MAXN][2],fa[MAXN],cnt,num,mid,lson,rson,sum[MAXN];
int tot[MAXN],sze[MAXN],root,val[MAXN],k,a[MAXN],p,l,r,ans;
inline void clear(int x){
    sze[x]=fa[x]=son[x][0]=son[x][1]=tot[x]=val[x]=sum[x]=0;
}
bool get(int x){
    return x==son[fa[x]][1];
}
inline void maintain(int x){
    sze[x]=sze[son[x][0]]+sze[son[x][1]]+tot[x];
    sum[x]=tot[x]*val[x]+sum[son[x][0]]+sum[son[x][1]];
}
inline void rotate(int x){
    int y=fa[x],z=fa[y],k=get(x);
    son[y][k]=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][son[z][1]==y]=x;
    maintain(y);
    maintain(x);
}
inline void splay(int x){
    for(int y=fa[x];y;rotate(x),y=fa[x])
        if(fa[y])
            rotate((get(x)==get(y))?y:x);
    root=x;
}
inline void insert(int k){
    if(!root){
        val[++cnt]=k;
        ++tot[cnt];
        root=cnt;
        maintain(root);
        return;
    }
    int x=root,y=0;
    while(1){
        if(val[x]==k){
            ++tot[x];
            maintain(x);
            maintain(y);
            splay(x);
            break;
        }
        y=x;
        x=son[x][(val[x]<k)];
        if(!x){
            val[++cnt]=k;
            ++tot[cnt];
            fa[cnt]=y;
            son[y][(val[y]<k)]=cnt;
            maintain(cnt);
            maintain(y);
            splay(cnt);
            break;
        }
    }
}
inline int find_num(int k){
    int x=root;
    if(sze[x]<k)
     	return -1;
    while(1){
        if(son[x][0]&&k<=sze[son[x][0]])
            rson+=tot[x]*val[x]+sum[son[x][1]],x=son[x][0];
        else{
            int temp=sze[son[x][0]]+tot[x];
            if(k<=temp){
            	lson+=(k-sze[son[x][0]]-1)*val[x]+sum[son[x][0]];
            	rson+=sum[son[x][1]]+val[x]*(sze[son[x][0]]+tot[x]-k);
            	return val[x];
            }
            lson+=tot[x]*val[x]+sum[son[x][0]];
            k-=temp;
            x=son[x][1];
        }
    }
}
inline int find_rank(int k)
{
	int ans=0,x=root;
	if(!x)
		return -1;
	while(1){
		if(k<val[x])
			x=son[x][0];
		else{
			ans+=sze[son[x][0]];
			if(k==val[x]){
				splay(x);
				return ans+1;
			}
			ans+=tot[x];
			x=son[x][1];
		}
	}
}
inline int pre()
{
    int x=son[root][0];
    while(son[x][1])
        x=son[x][1];
    splay(x);
    return x;
}
inline int nxt()
{
	int x=son[root][1];
	while(son[x][0])
		x=son[x][0];
	splay(x);
	return x;
}
inline void del(int k)
{
    int temp=find_rank(k);
    if(temp==-1)
    	return;
    if(tot[root]>1){
        --tot[root];
        maintain(root);
        return;
    }
    else if(!son[root][0]&&!son[root][1]){
        clear(root);
        root=0;
        return;
    }
    else if(!son[root][0]){
        int x=root;
        root=son[x][1];
        fa[root]=0;
        clear(x);
        return;
    }
    else if(!son[root][1]){
        int x=root;
        root=son[x][0];
        fa[root]=0;
        clear(x);
        return;
    }
    int x=root,pre1=pre();
    fa[son[x][1]]=pre1;
    son[pre1][1]=son[x][1];
    clear(x);
    maintain(root);
}
signed main(){
	cin>>n>>k;
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	for(int i=1;i<=k;i++)
		insert(a[i]);
	p=(k+1)>>1,l=1,r=k;
	mid=find_num(p),ans=(p-1)*mid-lson+rson-(k-p)*mid;
    for(int i=k+1;i<=n;i++){
    	insert(a[i]),del(a[i-k]);
    	lson=0,rson=0;
    	int kth=find_num(p);
    	int temp=(p-1)*kth-lson+rson-(k-p)*kth;
    	if(temp<ans)
			ans=temp,mid=temp,l=i-k+1,r=i;
    }
    cout<<ans<<'\n';
    for(int i=1;i<=n;i++)
    	if(i>=l&&i<=r)
    		cout<<mid<<'\n';
    	else
    		cout<<a[i]<<'\n';
    return 0;
}
2023/11/9 20:21
加载中...