zoukankan      html  css  js  c++  java
  • [HNOI2010] 弹飞绵羊

    题目链接:戳我
    比较模板的LCT了。。。。
    如果是更改操作的话就是先断开它和原先往后弹到的那个边,之后再连上新边。
    如果是查询操作就询问它到弹飞点的距离。
    那么弹飞点如何处理呢?就是新开一个点(比如说n+1)当某个点如果会被弹飞的话就向它连一条边即可。
    注意函数中x,y的先后关系是有影响的。
    其他就没有什么了,就是LCT的普通操作啦。
    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 200010
    using namespace std;
    int n,m,tot,to,op,cur,p;
    int s[MAXN];
    struct Node{int ch[2],val,ff,rev,son;}t[MAXN];
    inline int ls(int x){return t[x].ch[0];}
    inline int rs(int x){return t[x].ch[1];}
    inline void push_up(int x){t[x].son=t[ls(x)].son+t[rs(x)].son+1;}
    inline bool isroot(int x){return (ls(t[x].ff)!=x)&&(rs(t[x].ff)!=x);}
    inline void push_down(int x)
    {
        if(t[x].rev==0) return;
        t[ls(x)].rev^=1,t[rs(x)].rev^=1;
        swap(t[x].ch[0],t[x].ch[1]);
        t[x].rev^=1;
    }
    inline void rotate(int x)
    {
        int y=t[x].ff;
        int z=t[y].ff;
        int k=t[y].ch[1]==x;
        if(!isroot(y)) t[z].ch[t[z].ch[1]==y]=x; t[x].ff=z;
        t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].ff=y;
        t[x].ch[k^1]=y; t[y].ff=x;
        push_up(y),push_up(x);
    }
    inline void splay(int x)
    {
        s[tot=1]=x;
        for(int i=x;!isroot(i);i=t[i].ff) s[++tot]=t[i].ff;
        while(tot) push_down(s[tot--]);
        while(!isroot(x))
        {
            int y=t[x].ff,z=t[y].ff;
            if(!isroot(y))
                ((t[y].ch[0]==x)^(t[z].ch[0]==y))?rotate(x):rotate(y);
            rotate(x);
        }
    }
    inline void access(int x)
    {   
        for(int y=0;x;y=x,x=t[x].ff)  
            splay(x),t[x].ch[1]=y,push_up(x);
    }
    inline void makeroot(int x){access(x);splay(x);t[x].rev^=1;}
    inline void split(int x,int y){makeroot(x);access(y);splay(y);}
    inline void cut(int x,int y){split(x,y);t[y].ch[0]=t[x].ff=0;}
    inline void link(int x,int y){makeroot(x);t[x].ff=y;}
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d",&n);
        to=n+1;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&t[i].val);
            t[i].son=1;
            if(t[i].val+i>n) link(to,i); 
            else link(i+t[i].val,i);
        }
        t[n+1].son=1;
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&op,&cur);cur++;
            if(op==1)
            {
                split(to,cur);
                printf("%d
    ",t[cur].son-1);
            }
            else
            {
                scanf("%d",&p);
                if(t[cur].val+cur>n) cut(to,cur);
                else cut(t[cur].val+cur,cur);
                t[cur].val=p;
                link(cur,min(t[cur].val+cur,to));
            }
        }
    }
    
  • 相关阅读:
    2、细节&Class对象
    1、概述&应用场景
    Magento请求分发与控制器
    Magento强大的配置系统
    ecshop在PHP 5.4以上版本各种错误问题处理
    Thinkphp单字母函数使用指南
    五种常见的 PHP 设计模式
    MyISAM和InnoDB的区别
    linux下如何删除文件夹
    Linux软件安装与卸载
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10285376.html
Copyright © 2011-2022 走看看