[HNOI2010]弹飞绵羊

本文介绍了一个基于链状树结构(LCT)的游戏路径寻优问题。游戏由一系列带有弹力系数的装置构成,通过调整这些系数,玩家可以改变游戏路径。文章详细解释了如何使用LCT来高效地维护和更新这些路径,并提供了一个具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门

Description

某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。

Solution

水题已经越来越少了呢

首先发现所有路径组成一个树的结构,每次修改相当于移动一整棵子树

直接\(LCT\)维护即可

发现距离就是链的\(siz-1\),直接\(access\)一下就行


Code 

#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)>(b)?(b):(a))
#define reg register
using namespace std;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
const int MN=2e5+5; 
class Link_Cut_Tree
{        
    int c[MN][2],fa[MN],siz[MN];
    bool get(int x){return c[fa[x]][1]==x;}
    bool nrt(int x){return c[fa[x]][0]==x||c[fa[x]][1]==x;}
    void up(int x){siz[x]=siz[c[x][1]]+siz[c[x][0]]+1;}
    int rtt(int x)
    {
        int y=fa[x],z=fa[y],l=get(x),r=l^1;if(nrt(y))c[z][get(y)]=x;fa[x]=z;
        fa[c[x][r]]=y;c[y][l]=c[x][r];c[x][r]=y;fa[y]=x;up(y);
    }
    void Splay(int x)
    {
        for(;nrt(x);rtt(x))
            if(nrt(fa[x])) rtt(get(x)^get(fa[x])?x:fa[x]);
        up(x);
    }
    void acs(int x){for(reg int i=0;x;x=fa[i=x])Splay(x),c[x][1]=i,up(x);}
    public:
        void init(int N){for(reg int i=1;i<=N+1;++i)siz[i]=1;}
        void link(int x,int y){fa[x]=y;}
        void cut(int x){acs(x);Splay(x);fa[c[x][0]]=0;c[x][0]=0;up(x);}
        int que(int x){acs(x);Splay(x);return siz[x]-1;}
}T;
int k[MN];
int main()
{
    reg int i,N,M;N=read();T.init(N);
    for(i=1;i<=N;++i) k[i]=read(),T.link(i,min(i+k[i],N+1));
    M=read();
    while(M--)
    {
        i=read();
        if(i==1) printf("%d\n",T.que(read()+1));
        else i=read()+1,T.cut(i),k[i]=read(),T.link(i,min(i+k[i],N+1));
    }
    return 0;
}



Blog来自PaperCloud,未经允许,请勿转载,TKS!

转载于:https://www.cnblogs.com/PaperCloud/p/10660135.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值