ST表+分治(?求调
查看原帖
ST表+分治(?求调
299922
atarashiTLE楼主2023/10/1 13:13

Rt.10pts.思路自己胡的,题解里没。

大概就是ST表维护区间中第一个到达自己位置的bessieii,然后这只bessie(ii)之后的所有牛的到达时间加上(TiT_i)后面的不管,分治处理

code很短(或者可以证伪思路)

#include<bits/stdc++.h>
#define int long long
#define dlt(a) (n-i+s[a])
#define Min(a,b) ((ST[a][__lg(b-a+1)]<ST[b-(1<<__lg(b-a+1))+1][__lg(b-a+1)])?\
				   stag[a][__lg(b-a+1)]:((ST[a][__lg(b-a+1)]==ST[b-(1<<__lg(b-a+1))+1][__lg(b-a+1)])?a:stag[b-(1<<__lg(b-a+1))+1][__lg(b-a+1)]))
#define N 400010
using namespace std;
int n,s[N],t[N],ST[N][20],stag[N][20];
int fz(int l,int r,int nwPlaceOfR){
	if(l==r)return t[l];
 	if(r<l)return -2147483647;
	int m=Min(l,r);
	return max(fz(l,m-1,s[m]-1)+t[m],fz(m+1,r,s[m]+r-m))+s[m]+r-m-nwPlaceOfR;
}
signed main(){
	memset(ST,0x3f,sizeof(ST));
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>s[i]>>t[i];
		ST[i][0]=dlt(i);
		stag[i][0]=i;
	} 
	for(int j=1;j<=18;j++)
		for(int i=1;i<=n;i++)
			if(ST[i][j-1]<=ST[i+(1<<(j-1))][j-1])
				ST[i][j]=ST[i][j-1],stag[i][j]=stag[i][j-1];
			else
				ST[i][j]=ST[i+(1<<(j-1))][j-1],stag[i][j]=stag[i+(1<<(j-1))][j-1];
	cout<<fz(1,n,0)<<endl;
	return 0;
}

另,验证码c4fj[笑]

2023/10/1 13:13
加载中...