码迷,mamicode.com
首页 > 其他好文 > 详细

题解 CF13E 【Holes】

时间:2020-01-22 23:49:29      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:lct   main   getc   mat   make   namespace   def   pre   OLE   

这个题和\(P3203\\)弹飞绵羊基本上完全一致

我的做法是用\(LCT\)维护信息,开一个节点\(fly\),表示到此节点时,小球会弹飞,那么查询弹多少次即为\(siz[fly]-1\)

最后一次落在哪个洞可以用维护链上最大值来解决

一些小细节看代码就行了

\(code:\)

#include<bits/stdc++.h>
#define maxn 400010
using namespace std;
template<typename T> inline void read(T &x)
{
    x=0;char c=getchar();bool flag=false;
    while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    if(flag)x=-x;
}
int n,m,flag,root,tot,fly;
int p[maxn],fa[maxn],ch[maxn][2],siz[maxn],ma[maxn],rev[maxn];
bool check(int x)
{
    return ch[fa[x]][1]==x;
}
void pushr(int x)
{
    rev[x]^=1;swap(ch[x][0],ch[x][1]);
}
void pushup(int x)
{
    siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
    if(x!=fly) ma[x]=max(x,max(ma[ch[x][0]],ma[ch[x][1]]));
    else ma[x]=max(ma[ch[x][0]],ma[ch[x][1]]);
}
void pushdown(int x)
{
    if(!rev[x]) return;
    pushr(ch[x][0]),pushr(ch[x][1]);
    rev[x]=0;
}
bool notroot(int x)
{
    return ch[fa[x]][0]==x||ch[fa[x]][1]==x;
}
void rotate(int x)
{
    int y=fa[x],z=fa[y],k=check(x),w=ch[x][k^1];
    if(notroot(y)) ch[z][check(y)]=x;
    fa[x]=z;
    ch[y][k]=w;
    if(w) fa[w]=y;
    ch[x][k^1]=y;
    fa[y]=x;
    pushup(y);
}
void all(int x)
{
    if(notroot(x)) all(fa[x]);
    pushdown(x);
}
void splay(int x)
{
    all(x);
    for(int y;notroot(x);rotate(x))
        if(notroot(y=fa[x]))
            rotate(check(x)^check(y)?x:y);
    pushup(x);
}
void access(int x)
{
    for(int y=0;x;y=x,x=fa[x])
        splay(x),ch[x][1]=y;
}
void makeroot(int x)
{
    access(x),splay(x),pushr(x);
}
void split(int x,int y)
{
    makeroot(x),access(y),splay(y);
}
void link(int x,int y)
{
    split(x,y),fa[x]=y;
}
void cut(int x,int y)
{
    split(x,y),fa[x]=ch[y][0]=0;
}
int main()
{
    read(n),read(m);
    fly=n+1;
    for(int i=1;i<=n;++i)
    {
        read(p[i]);
        if(i+p[i]<=n) link(i,i+p[i]);
        else link(i,fly);
    }
    while(m--)
    {
        int x,y;
        read(flag);
        if(flag)
        {
            read(x);
            split(x,fly);
            printf("%d %d\n",ma[fly],siz[fly]-1);
        }
        else
        {
            read(x),read(y);
            if(x+p[x]<=n) cut(x,x+p[x]);
            else cut(x,fly);
            p[x]=y;
            if(x+p[x]<=n) link(x,x+p[x]);
            else link(x,fly);
        }
    }
    return 0;
}

题解 CF13E 【Holes】

标签:lct   main   getc   mat   make   namespace   def   pre   OLE   

原文地址:https://www.cnblogs.com/lhm-/p/12229813.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!