5pts
查看原帖
5pts
627867
lyc1001楼主2023/3/31 21:23

树状数组维护前驱后继+简易倍增,不知道哪里挂了

#include<iostream>
#include<algorithm>
#include<cmath>
#define N 100005
#define int long long
using namespace std;
long long xa[N][20],xb[N][20];
double minn=1e9+5;
int a1,b1,ans=N,fa[N][20],a[N],id[N],n,h[N],m,c[140000],ls[N],x,up[N],dn[N],fst[N],scd[N];
void lsh()//离散化 
{
	sort(ls+1,ls+1+n);
	for(int i=1;i<=n;i++)
	{
		h[i]=lower_bound(ls+1,ls+1+n,h[i])-ls;//无误 
		id[h[i]]=i;
	}
	a[n+1]=ls[n+1]=5e9+5;
	a[n+2]=ls[n+2]=a[N]=-5e9-5;
}
int dis(int posa,int posb)
{
	return abs(a[posa]-a[posb]);
}
//tree 
int lowbit(int x)
{
	return x&-x;
}
void upd(int x,int k)
{
	while(x<=n)
	{
		c[x]+=k;
		x+=lowbit(x);
	}
}
int getsum(int x)
{
	int sum=0;
	while(x)
	{
		sum+=c[x];
		x-=lowbit(x);
	}
	return sum;
}
int kth(int x)
{
	int now=0,sum=0;
	for(int i=17;i>=0;i--)
	{
		if(now+(1<<i)<=n&&sum+c[now+(1<<i)]<x)
		{
			sum+=c[1<<i];
			now+=(1<<i);
		}
	}
	return now+1;
}
//
void mem()//求出第一第二近 
{
	for(int i=n;i>=1;i--)
	{
		upd(h[i],1);
		int res=getsum(h[i]);
		if(res<n-i+1)
		{
			up[i]=id[kth(res+1)];
		}
		if(res>1)dn[i]=id[kth(res-1)];
		if(up[i]==0)up[i]=n+1;
		if(dn[i]==0)dn[i]=n+2; 
	}
	for(int i=n;i>=1;i--)
	{
		if(a[i]-a[dn[i]]<=a[up[i]]-a[i])
		{
			fst[i]=dn[i];
			if(a[i]-a[dn[dn[i]]]<=a[up[i]]-a[i])
			{
				scd[i]=dn[dn[i]];
			}
			else scd[i]=up[i];
		}
		else
		{
			fst[i]=up[i];
			if(a[i]-a[dn[i]]<=a[up[up[i]]]-a[i])
			{
				scd[i]=dn[i];
			}
			else scd[i]=up[up[i]];
		}
	}
	for(int i=1;i<=n;i++)
	{
		fa[i][0]=fst[scd[i]];
		xa[i][0]=dis(i,scd[i]);
		xb[i][0]=dis(scd[i],fst[scd[i]]);
	}
	for(int i=1;i<=17;i++)
	{
		for(int j=1;j<=n;j++)
		{
			fa[j][i]=fa[fa[j][i-1]][i-1];
			xa[j][i]=xa[j][i-1]+xa[fa[j][i-1]][i-1];
			xb[j][i]=xb[j][i-1]+xb[fa[j][i-1]][i-1];
		}
	}
}
int binary(int pos,int x)
{
	a1=b1=0;
	for(int i=17;i>=0;i--)
	{
		if(fa[pos][i]<=n&&fa[pos][i]>0&&xa[pos][i]+xb[pos][i]<x)
		{
			a1+=xa[pos][i];
			b1+=xb[pos][i];
			x-=xa[pos][i]+xb[pos][i];
			pos=fa[pos][i];
		}
	}
	if(x>=xa[pos][0])a1+=xa[pos][0];
}
signed main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>h[i];
		a[i]=ls[i]=h[i];
	}
	lsh();
	mem();
	cin>>x>>m;
	for(int i=1;i<=n;i++)
	{
		binary(i,x);
		if(b1==0)
		{
			if(a[ans]<a[i]&&minn==1e9+5)ans=i;
		}
		else
		{
			if(a1*1.0/b1<minn||(a1*1.0/b1==minn&&a[ans]<a[i]))minn=a1*1.0/b1,ans=i;
		}
	}
	cout<<ans<<"\n";
	while(m--)
	{
		int s,x;
		cin>>s>>x;
		binary(s,x);
		cout<<a1<<" "<<b1<<"\n";
	}
}
2023/3/31 21:23
加载中...