其他分享
首页 > 其他分享> > * ! AHOI/HNOI2018转盘

* ! AHOI/HNOI2018转盘

作者:互联网


线段树维护单调栈

又是一道非常棒的思维题!!!


SOL:

问题转化(倒着思考)

t时刻在某点,每次可以向后走一步或留在原地,然后t减1

每个点在\(T_i\)消失,求最小的\(t\)使得所有点都可以在消失前被访问

于是惊奇地发现留在原地一定不优,会一直往前走

破环为链(2倍),对于\(i\in[n,2n)\)走到j的时间为\(t-(i-j)\)

\(j\in(i-n]\)满足\(t-(i-j)>=T_j\to t_{min}=max(T_j-j)+i\)

\(ans=min_{i\in[n,2n)}(max_{j\in(i-n,i]}a_j+i),a_j=T_j-j\)

用i代替i+n-1

\(ans=min_{i\in[1,n])}(max_{j\in[i,2n]}a_j+i)+n-1\)因为\(a_i>a_{i+n}\)

若\(a_j\)为后缀最大值,i为j前第一个比\(a_j\)大的位置,\(ans=a_j+i+n\)

需要维护一个单调栈

线段树维护单调栈——楼房重建

每个区间记录最大值及单调栈长度,合并时左边肯定都是单调栈的内容,右边二分一个位置恰好大于左边分最大值则剩余的加入单调栈,时间复杂度\(O(nlog_n^2)\)

\(p_0,p_1,…,p_k\)是栈里留下的元素

\(p_{j-1}<n<=p_j\)

\(ans=min_{i\in[1,j]}(a_{p_i}+p_{i-1})+n\)

因为\((n,2n]\)里的最大值是\([1,n]\)里的最大值-n,所以只用维护\([1,n]\)

记\(mx[p]\)为区间最大值,\(t[p]\)为区间左半到中间的最小答案

\(ans=query(1,1,n,mx[1]-n)\)

时间复杂度\(O(nlog_n^2)\)

#include<bits/stdc++.h>
using namespace std;
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return f==1?x:-x;
}
const int N=1e5+4,inf=1e9;
int n,m,op,ans,a[N],mx[N<<2],t[N<<2];
#define lc (p<<1)
#define rc (p<<1|1)
int query(int p,int l,int r,int x){
	if(l==r)return mx[p]>x?x+l:inf;
	int mid=l+r>>1;
	return mx[rc]>x?min(t[p],query(rc,mid+1,r,x)):query(lc,l,mid,x);
}
inline void pushup(int p,int l,int r){
	mx[p]=max(mx[lc],mx[rc]);
	t[p]=query(lc,l,r,mx[rc]);
}
void build(int p,int l,int r){
	if(l==r){
		mx[p]=a[l]-l;
		return;
	}
	int mid=l+r>>1;
	build(lc,l,mid);
	build(rc,mid+1,r);
	pushup(p,l,mid);
}
void modify(int p,int l,int r,int x,int y){
	if(l==r){
		mx[p]=y-x;
		return;
	}
	int mid=l+r>>1;
	if(x<=mid)modify(lc,l,mid,x,y);
	else modify(rc,mid+1,r,x,y);
	pushup(p,l,mid);
}
int main(){
	n=read();m=read();op=read();
	for(int i=1;i<=n;i++)a[i]=read();
	build(1,1,n);
	ans=query(1,1,n,mx[1]-n)+n;
	cout<<ans<<"\n";
	while(m--){
		static int x,y;
		x=read();y=read();
		if(op){x^=ans;y^=ans;}
		modify(1,1,n,x,y);
		ans=query(1,1,n,mx[1]-n)+n;
		cout<<ans<<"\n";
	}
	return (0-0);
}

标签:AHOI,int,最大值,ans,mid,rc,HNOI2018,mx,转盘
来源: https://www.cnblogs.com/aurora2004/p/12604395.html