1、题目大意:就是给一个动态的森林求size域

2、分析: 这个就是一个动态树问题,对于每一个位置i有i+ki这个父亲, 于是这就是一个森林了,然后对于每一个修改直接lct维护就好,询问就是i到最外面的点的个数,恰好是一个链,就求一个
size就好

#include <stack>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
#define eps 1e-7
int n, m;
    struct Node{
        Node *ch[2], *fa;
        bool rev;
        int size;
        inline int which();
        inline bool reverse(){
            if(this) rev ^= 1;
        }
        inline void pd(){
            if(rev){
                swap(ch[0], ch[1]);
                ch[0] -> reverse();
                ch[1] -> reverse();
                rev = false;
            }
        }
        inline void maintain(){
            size = 1;
            size += ch[0] -> size;
            size += ch[1] -> size;
        }
        Node();
    } *null = new Node, pos[200010];
    Node::Node(){
            ch[0] = ch[1] = null;
            fa = null;
            size = 1;
            rev = false;
    }
    inline int Node::which(){
        if(fa == null || (fa -> ch[0] != this && fa -> ch[1] != this)) return -1;
        return fa -> ch[1] == this;
    }
    inline void rotate(Node *o){
        Node *p = o -> fa;
        int l = o -> which(), r = l ^ 1;
        o -> fa = p -> fa;
        if(p -> which() != -1) p -> fa -> ch[p -> which()] = o;
        p -> ch[l] = o -> ch[r];
        if(o -> ch[r]) o -> ch[r] -> fa = p;
        o -> ch[r] = p; p -> fa = o;
        o -> ch[r] -> maintain();
        o -> maintain();
    } 

    inline void splay(Node* o){
        static stack<Node*> st;
        if(!o) return;
        Node* p = o;
        while(1){
            st.push(p);
            if(p -> which() == -1) break;
            p = p -> fa;
        }
        while(!st.empty()){
            st.top() -> pd(); st.pop();
        }

        while(o -> which() != -1){
            p = o -> fa;
            if(p -> which() != -1){
                if(p -> which() ^ o -> which()) rotate(o);
                else rotate(p);
            }
            rotate(o);
        }
    }

    inline void Access(Node* o){
        Node* p = null;
        while(o != null){
            splay(o);
            o -> ch[1] = p;
            o -> maintain();
            p = o; o = o -> fa;
        }
    }

    inline void Link(Node* x, Node* y){
        Access(x);
        splay(x);
        if(x -> ch[0]) x -> ch[0] -> fa = null;
        x -> ch[0] = null;
        x -> fa = y;
        x -> maintain();
    }

int main(){
    null->ch[0]=null->ch[1]=null->fa=NULL;
    null->size=0;
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++){
        int y; scanf("%d", &y);
        if(i + y <= n) pos[i].fa = &pos[i + y];
    }
    scanf("%d", &m);
    while(m --){
        int op, x, y;
        scanf("%d", &op);
        if(op == 1){
            scanf("%d", &x); x ++;
            Access(&pos[x]);
            splay(&pos[x]);
            printf("%d\n", pos[x].size);
        }
        else{
            scanf("%d%d", &x, &y); x ++;
            if(x + y <= n)   Link(&pos[x], &pos[x+y]);
            else Link(&pos[x], null);
        }
    }
    return 0;
}

BZOJ2002——[Hnoi2010]Bounce 弹飞绵羊的更多相关文章

  1. BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 【LCT】【分块】

    BZOJ2002 Hnoi2010 Bounce 弹飞绵羊 Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始, ...

  2. [bzoj2002][Hnoi2010]Bounce弹飞绵羊_LCT

    Bounce弹飞绵羊 bzoj-2002 Hnoi-2010 题目大意:n个格子,每一个格子有一个弹簧,第i个格子会将经过的绵羊往后弹k[i]个,达到i+k[i].如果i+k[i]不存在,就表示这只绵 ...

  3. bzoj2002: [Hnoi2010]Bounce 弹飞绵羊 [分块][LCT]

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...

  4. [BZOJ2002] [Hnoi2010] Bounce 弹飞绵羊 (LCT)

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...

  5. [bzoj2002][Hnoi2010]Bounce弹飞绵羊——分块

    Brief description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装 ...

  6. BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊(LCT)

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在 他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装 ...

  7. bzoj2002 [Hnoi2010]Bounce 弹飞绵羊——分块

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 第一次用分块,感觉超方便啊: 如果记录每个点的弹力系数,那么是O(1)修改O(n)查询 ...

  8. bzoj2002 [Hnoi2010]Bounce 弹飞绵羊【分块】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2002 这一题除了LCT解法,还有一种更巧妙,代码量更少的解法,就是分块.先想,如果仅仅记录每 ...

  9. 题解【bzoj2002 [Hnoi2010]Bounce 弹飞绵羊】

    Description 给 \(n\) 个点以及它们的弹力系数 \(k_i\) ,含义为 可以弹到 \(i + k_i\) 的位置. 支持两个东西,修改一个点的弹力系数:求一个点要弹多少次弹出 \(n ...

  10. 【lct】bzoj2002 [Hnoi2010]Bounce 弹飞绵羊

    lct板子,此题主要有cut操作和link操作. #include<cstdio> #include<iostream> #include<cstring> #in ...

随机推荐

  1. photoshop工具使用的简单介绍

    photoshop工具使用的简单介绍 我所用PhotoShop版本号是cs6,这里对其主要功能做一个简单介绍. 第一部分: 首先,ps的界面主要分为了6部分: 一.最上面的一行的菜单栏,菜单中有:文件 ...

  2. segmentfault.com mongo出识以及对数组的操作

    https://segmentfault.com/a/1190000003951602 首先推荐个工具,no-sql-manager-for-mongodb-professional,虽然收费,但是每 ...

  3. 什么是jsonp

    Jsonp其实就是一个跨域解决方案. Js跨域请求数据是不可以的,但是js跨域请求js脚本是可以的. 所以可以把要请求的数据封装成一个js语句,做一个方法的调用. 跨域请求js脚本可以得到此脚本.得到 ...

  4. BigDecimal 类型数据的一些应用

    1.比较大小 可以通过BigDecimal的compareTo方法来进行比较.返回的结果是int类型,-1表示小于,0是等于,1是大于. 例如: if(a.compareTo(b) == -1){ a ...

  5. C#读写文本文件

    static public string Read(string path) { StreamReader sr = new StreamReader(path,Encoding.Default); ...

  6. apache无法正常启动,80端口被占用的解决方法

    apache无法正常启动,80端口被占用的解决方法 网上的方法: 仔细查看提示: make_sock: could not bind to address 0.0.0.0:80 恍然大悟,计算机上安装 ...

  7. lua 元表

    Set = {} Set.mt = {} function Set.new(t) local set = {} setmetatable(set, Set.mt) for _, l in ipairs ...

  8. WSAStartup

    WSAStartup,是Windows Sockets Asynchronous的启动命令.Windows下的网络编程接口软件 Winsock1 或 Winsock2 里面的一个命令. 外文名 WSA ...

  9. 使用RawSocket进行网络抓包

    aw socket,即原始套接字,可以接收本机网卡上的数据帧或者数据包,对与监听网络的流量和分析是很有作用的,一共可以有3种方式创建这种socket. 中文名 原始套接字 外文名 RAW SOCKET ...

  10. Java实例分析:宠物商店

    设计一个“宠物商店”,在宠物商店中可以有多种宠物,试表示出此种关系,并要求可以根据宠物的关键字查找相应的宠物信息. //======================================== ...