zoukankan      html  css  js  c++  java
  • 洛谷 P3203 [HNOI2010]弹飞绵羊 解题报告

    P3203 [HNOI2010]弹飞绵羊

    题目描述

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

    输入输出格式

    输入格式:

    第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1。

    接下来一行有n个正整数,依次为那n个装置的初始弹力系数。

    第三行有一个正整数m,

    接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。

    输出格式:

    对于每个i=1的情况,你都要输出一个需要的步数,占一行。

    说明

    对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000


    抽象一下问题,将弹飞的连到虚点(n+1)上,则图是一颗树,我们需要一个能修改边的,查询深度的连喵树。

    我们发现其实不需要换根操作(然而本菜鸡最开始还打了)

    (link)时提一个连一个虚边就行了

    (cat)的时候把浅的(access)上去以后把深的(splay)一下然后直接断虚边

    (query)(access)一下,(splay)一下,就是左儿子大小。

    事实上可以更简单


    Code:

    #include <cstdio>
    #define ls ch[now][0]
    #define rs ch[now][1]
    #define fa par[now]
    int min(int x,int y){return x<y?x:y;}
    const int N=2e5+10;
    int ch[N][2],siz[N],par[N],n,m,tmp,to[N];
    bool isroot(int now)
    {
        return ch[fa][0]==now||ch[fa][1]==now;
    }
    int identity(int now)
    {
        return ch[fa][1]==now;
    }
    void updata(int now)
    {
        siz[now]=siz[ls]+siz[rs]+1;
    }
    void connect(int f,int now,int typ)
    {
        fa=f;ch[f][typ]=now;
    }
    void Rotote(int now)
    {
        int p=fa,typ=identity(now);
        connect(p,ch[now][typ^1],typ);
        if(isroot(p)) connect(par[p],now,identity(p));
        else fa=par[p];
        connect(now,p,typ^1);
        updata(p),updata(now);
    }
    void splay(int now)
    {
        for(;isroot(now);Rotote(now))
            if(isroot(fa))
                Rotote(identity(now)^identity(fa)?now:fa);
    }
    void access(int now)
    {
        for(int las=0;now;las=now,now=fa)
            splay(now),rs=las,updata(now);
    }
    void link(int u,int v)
    {
        access(v);
        splay(u);
        par[u]=v;
    }
    void cat(int u,int v)
    {
        access(v);
        splay(u);
        par[u]=0;
    }
    int query(int now)
    {
        access(now);
        splay(now);
        return siz[ls];
    }
    int main()
    {
        scanf("%d",&n);
        for(int k,i=1;i<=n;i++)
        {
            scanf("%d",&k);
            par[i]=min(i+k,n+1);
            to[i]=par[i];
        }
        scanf("%d",&m);
        for(int op,u,k,i=1;i<=m;i++)
        {
            scanf("%d%d",&op,&u);++u;
            if(op==1) printf("%d
    ",query(u));
            else
            {
                scanf("%d",&k);
                cat(u,to[u]);
                to[u]=min(u+k,n+1);
                link(u,to[u]);
            }
        }
        return 0;
    }
    
    

    2018.8.11

  • 相关阅读:
    android 内存泄漏分析
    sublime text3
    Bind Service 不会在后台无限期的一直运行
    uint8_t / uint16_t / uint32_t /uint64_t 是什么数据类型?
    #include < >与#include “ ”
    什么是库?
    gcc编译器
    如何写C语言程序
    ubuntu登陆root用户验证失败
    nginx location匹配顺序及CI框架的nginx配置
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9460405.html
Copyright © 2011-2022 走看看