20分线段树
查看原帖
20分线段树
347832
tony_wind楼主2022/10/28 20:00
#include<bits/stdc++.h>
using namespace std;
const int N = 5e4+50,inf = 0xfffffff;
int l,n,m;
int a[N],f[N];

int get(int x){
	return f[x] = x ? x: f[x] = get(f[x]);
}

struct tree{
	int mn[4*N],w[4*N],re[4*N];
	
	void build(int l,int r,int p)
	{
		if(l == r){
			 mn[p] = a[l] - a[l-1];
			 w[p] = l;
			 re[l] = p;
			 return;
		}
		int mid = l + r >> 1;
		build( l, mid, p*2);build( mid+1, r, p*2+1);
		if(mn[p*2] >= mn[p*2+1]) mn[p] = mn[p*2+1],w[p] = w[p*2+1];
		else mn[p] = mn[p*2],w[p] = w[p*2];
		return ;
	}
	
	void change(int l ,int r,int k,int nw, int p)
	{
		if(l == r){
			mn[p] = nw;return ;
		}
		int mid = l + r >> 1;
		if( k <= mid )change( l, mid, k, nw, p*2);
		else change(mid+1, r, k ,nw, p*2+1);
		
		if(mn[p*2] >= mn[p*2+1]) mn[p] = mn[p*2+1],w[p] = w[p*2+1];
		else mn[p] = mn[p*2],w[p] = w[p*2];
		
		return ;
	}
	
	
}tr;




int main(){
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	cin>>l>>n>>m;
	a[n+1] = l;
	for(int i = 1; i <= n; i++)cin>>a[i];
	
	tr.build(1,n+1,1);
	
	for(int i = 1; i <= m; i++)
	{
		int id = tr.w[1];
		int l = id + 1,r = n + 1,r_mid = l+r>>1;
		while(l <= r)
		{
			r_mid = l + r>>1;
			if(get(r_mid) == get(tr.w[1]) )l = r_mid+1;
			else r = r_mid-1;
		}
		
		l = 1,r = id - 1;int l_mid = l+r>>1;
		
		while(l <= r)
		{
			l_mid = l + r>>1;
			if(get(l_mid) == get(tr.w[1]) )r = l_mid-1;
			else l = l_mid+1;
		}
		
		int ng = 0;
		if(r_mid == id)ng = l_mid;
		else if(l_mid == id) ng = r_mid;
		else {
			if(tr.re[l_mid] > tr.re[r_mid] )ng = r_mid;
			else ng = l_mid;
		}
		f[id]  = f[ng];
		tr.change(1, n, ng, tr.re[ng] + tr.re[id], 1); tr.change(1, n, id, inf, 1);
	}
	
	cout<<tr.mn[1]<<endl;	
	
	return 0; 
}


2022/10/28 20:00
加载中...