题解 洛谷 P4425 【[HNOI/AHOI2018]转盘】

发现最优解可以表示为在起点等待一段时间,然后不停顿地走完一圈。因为停顿的原因是当前的物品没有出现,所以可以在起点先等待,然后不停顿地来标记。

对环倍长来将其转化为链,用 \(i\) 来枚举起始位置,\(j\) 来枚举物品,则答案可表示为:

\[\min\limits_{i=1}^n\left \{ i+\max\limits_{j=i}^{2n} \left \{t_j-j \right \} \right \} +n-1 \]

这里可以将 \(\max\) 的枚举范围扩大,因为扩大的部分不可能成为最大值,所以不影响答案。

考虑用线段树来维护答案,因为倍长后长度为 \(2n\),起始位置只可能为 \([1,n]\),所以对于一个区间,只维护左区间的答案即可。线段树上维护当前区间的答案和 \(t_i-i\) 的最大值,合并两个区间时,用右区间的最大值 \(v\) 在左区间二分即可。

具体地,若 \(v\) 比当前区间右区间的最大值大,则说明 \(mid\) 往右的最大值是 \(v\),右区间就直接返回左端点的答案即可,若 \(v\) 更小,就不用再进入左区间,区间返回当前区间的答案即可。

线段树根节点的答案即为所求。维护方法和楼房重建很像。

\(code:\)

#include<bits/stdc++.h>
#define maxn 800010
#define ls (cur<<1)
#define rs (cur<<1|1)
#define mid ((l+r)>>1)
using namespace std;
template<typename T> inline void read(T &x)
{
    x=0;char c=getchar();bool flag=false;
    while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    if(flag)x=-x;
}
int n,m,ans,p,root=1;
int t[maxn],ma[maxn],val[maxn];
int query(int l,int r,int v,int cur)
{
    if(l==r) return l+max(v,ma[cur]);
    if(v>=ma[rs]) return min(mid+1+v,query(l,mid,v,ls));
    return min(val[cur],query(mid+1,r,v,rs));
}
void pushup(int cur,int l,int r)
{
    ma[cur]=max(ma[ls],ma[rs]);
    val[cur]=query(l,mid,ma[rs],ls);
}
void build(int l,int r,int cur)
{
    if(l==r)
    {
        val[cur]=t[l],ma[cur]=t[l]-l;
        return;
    }
    build(l,mid,ls),build(mid+1,r,rs),pushup(cur,l,r);
}
void modify(int l,int r,int pos,int v,int cur)
{
    if(l==r)
    {
        val[cur]=v,ma[cur]=v-l;
        return;
    }
    if(pos<=mid) modify(l,mid,pos,v,ls);
    else modify(mid+1,r,pos,v,rs);
    pushup(cur,l,r);
}
int main()
{
    read(n),read(m),read(p);
    for(int i=1;i<=n;++i) read(t[i]),t[i+n]=t[i];
    build(1,2*n,root),printf("%d\n",ans=val[root]+n-1);
    while(m--)
    {
        int x,y;
        read(x),read(y),x^=ans*p,y^=ans*p;
        modify(1,2*n,x,y,root),modify(1,2*n,x+n,y,root);
        printf("%d\n",ans=val[root]+n-1);
    }
    return 0;
}
posted @ 2020-08-06 19:54  lhm_liu  阅读(199)  评论(0编辑  收藏  举报