记录编号 325278 评测结果 AAAAAAAAAA
题目名称 [HNOI 2010] 弹飞绵羊 最终得分 100
用户昵称 Gravatarsxysxy 是否通过 通过
代码语言 C++ 运行时间 1.616 s
提交时间 2016-10-19 13:38:09 内存使用 1.07 MiB
显示代码纯文本
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <list>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
struct node
{
    node *ch[2];
    #define LC ch[0]    
    #define RC ch[1]
    node *f;
    int size, rev;
    node():size(1), rev(0)
    {
        f = LC = RC = NULL;
    }
    void pushup()
    {
        size = 1;
        for(int i = 0; i <= 1; i++)if(ch[i])size += ch[i]->size;
    }
    void pushdown()
    {
        if(rev)
        {
            for(int i = 0; i <= 1; i++)if(ch[i])ch[i]->rev ^= 1;
            rev = 0;
            swap(LC, RC);
        }
    }
}soilder, *null = &soilder;

node *new_node()
{
    node *t = new node();
    t -> LC = t -> RC = t -> f = null;
}
class lct
{
public:
    inline bool is_root(node *t)
    {
        return t == null || (t->f->LC != t && t->f->RC != t);
    }
    
    void rotate(node *t) //把t往上旋
    {
        if(is_root(t))return;
        node *m = t->f;   //它的父节点
        if(!is_root(m))
        {
            if(m == m->f->LC) //是左孩子
                m->f->LC = t;
            else m->f->RC = t;  
        }
        t->f = m->f;
        //以上 用t替代了m的位置
        //-----------------------
        
        //这是一个单旋转
        int d = (t == m->RC);
        m->ch[d] = t->ch[d^1];
        if(t->ch[d^1])t->ch[d^1]->f = m;  //注意多维护了一个"父节点"信息。
        t->ch[d^1] = m;  
        m->f = t;    //m成了t的子节点
        m->pushup();
        //-------------------------
        
        //t成为了新的(这个子树的)根
        t->pushup();
    }
    
    /*
    void recalc(node *t)
    {
        stack<node *> s; //用一个栈,模拟递归顺序
        s.push(t);
        for(node *p = t; !is_root(p); p = p -> f)
            s.push(p -> f);
        while(s.size())
        {
            s.top() -> pushdown();
            s.pop();
        }
    }
    */
    void splay(node *t)
    {
        //recalc(t);   //太慢了...
        t -> pushdown();
        while(!is_root(t))
        {
            node *m = t->f;
            m -> f -> pushdown();  //从上往下的顺序pushdown
            m -> pushdown();
            t -> pushdown();
            if(is_root(m))   //m已经是根了
                rotate(t);   //t向上单旋一次,到根
            else
            {
                if(t == m->f->LC->LC || t == m->f->RC->RC) //t,m,m->f在一条线上
                    rotate(m); //也就是
                    //              m->f               m
                    //              /                 / \
                   //              m         ->      t  m->f(呸,它已经不是m的父节点了)
                   //             /
                   //            t               
                else
                    rotate(t);  //自行脑补
                rotate(t);
            }
        }
        t -> pushup();
    }
    node *access(node *t)
    {
        node *m = null;
        while(t != null)
        {
            splay(t);
            t -> RC = m;  //最开始一次t的RC变成了null,就是断开了...
            m -> f = t;
            t -> pushup();
            
            m = t;
            t = t -> f;
        }
        return m;
    }
    inline void makeroot(node *t)
    {
        access(t);
        splay(t);
        t -> rev ^= 1;
    }
    inline void link(node *t, node *m) //连接后t是m的孩子节点
    {
        makeroot(t);
        t -> f = m;
        access(t);
    }
    inline void cut(node *t)
    {
        access(t);
        splay(t);
        t -> LC = t -> LC -> f = null;
        t -> pushup();
    }
    bool is_connected(node *t, node *m)
    {
        while(t -> f != null)t = t -> f;
        while(m -> f != null)m = m -> f;
        return t == m;
    }
}t;

int fast_read()
{
    int r;
    char c;
    bool sig = false;
    while(c = getchar())    
    {
        if(c >= '0' && c <= '9')
        {
            r = c^0x30;
            break;
        }else if(c == '-')sig = true;
    }
    while(isdigit(c = getchar()))
        r = (r<<3)+(r<<1)+(c^0x30);
    return sig? -r:r;
}
void clear(int t)
{
    while(t--)getchar();
}
#define MAXN 200001
node *ns[MAXN];
int main()
{
    freopen("bzoj_2002.in", "r", stdin);
    freopen("bzoj_2002.out", "w", stdout);
    int n, m;
    n = fast_read();
    null -> size = 0;
    null -> LC = null -> RC = null -> f = null;
    for(int i = 0; i <= n; i++)
        ns[i] = new_node();
    for(int i = 0; i < n; i++)
        t.link(ns[i], ns[min(n, i+fast_read())]);
    m = fast_read();
    while(m--)
    {
        int op = fast_read();
        if(op == 1)
        {
            int a = fast_read();
            t.makeroot(ns[n]);
            t.access(ns[a]);
            t.splay(ns[a]);
            printf("%d\n", ns[a]->LC->size);
        }else
        {
            int a = fast_read();
            int b = fast_read();
            t.cut(ns[a]);
            t.link(ns[a], ns[min(n, a+b)]);
        }
    }
    return 0;
}