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

    P3203 [HNOI2010]弹飞绵羊

    思路

    每个点都往后面连边
    所以肯定没有环
    超过n的算连向n+1
    n+1个点,n条边,没有环,一定联通
    那就差不多是个树了
    然后就LCT模拟他的操作就行
    有比较简单的LCT做法,不过我还是喜欢无脑一点的

    错误

    cut操作x写错i

    代码

    #include <bits/stdc++.h>
    #define ls ch[x][0]
    #define rs ch[x][1]
    #define FOR(i,a,b) for(int i=a;i<=b;++i)
    using namespace std;
    const int N=2e5+7;
    int read() {
        int x=0,f=1;char s=getchar();
        for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
        for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
        return x*f;        
    }
    int a[N],f[N],ch[N][2],s[N],lazy[N];
    void pushup(int x) {s[x]=s[ls]+s[rs]+1;}
    void tag(int x) {swap(ls,rs);lazy[x]^=1;}
    bool isroot(int x) {return ch[f[x]][0]==x || ch[f[x]][1]==x;}
    void pushdown(int x) {
        if(lazy[x]) {
            if(ls) tag(ls);
            if(rs) tag(rs);
            lazy[x]=0;
        }
    }
    void rotate(int x) {
        int y=f[x],z=f[y],k=ch[y][1]==x,m=ch[x][k^1];
        if(isroot(y)) ch[z][ch[z][1]==y]=x;
        ch[x][k^1]=y;
        ch[y][k]=m;
        if(m) f[m]=y;
        f[x]=z;
        f[y]=x;
        pushup(y);
    }
    int Q[N];
    void splay(int x) {
        int y=x,z=0;
        Q[++z]=y;
        while(isroot(y)) Q[++z]=y=f[y];
        while(z) pushdown(Q[z--]);
        while(isroot(x)) {
            y=f[x],z=f[y];
            if(isroot(y)) (ch[y][0]==x)^(ch[z][0]==y) ? rotate(x) : rotate(y);
            rotate(x);
        }
        pushup(x);
    }
    void access(int x) {
        for(int y=0;x;y=x,x=f[x])
            splay(x),rs=y,pushup(x);
    }
    void makeroot(int x) {
        access(x);
        splay(x);
        tag(x);
    }
    int findroot(int x) {
        access(x);
        splay(x);
        while(ls) pushdown(x),x=ls;
        return x; 
    }
    void split(int x,int y) {
        makeroot(x);
        access(y);
        splay(y);
    }
    void link(int x,int y) {
        makeroot(x);
        if(findroot(y)!=x) f[x]=y;
    }
    void cut(int x,int y) {
        makeroot(x);
        if(findroot(y)==x&&f[x]==y&&!ch[x][1]) {
            f[x]=ch[y][0]=0;
            pushup(y);
        }
    }
    int main() {
        int n=read();
        FOR(i,1,n+1) s[i]=1;
        FOR(i,1,n) a[i]=read();
        FOR(i,1,n) {
            link(i,(i+a[i])>n ? n+1 : i+a[i]);
        }
        int m=read();
        FOR(i,1,m) {
            int opt=read(),x=read()+1;
            if(opt==1) {
                split(x,n+1);
                cout<<s[n+1]-1<<"
    ";
            } else {
                int y=read();
                cut(x,(a[x]+x)>n ? n+1 : a[x]+x);
                a[x]=y;
                link(x,(a[x]+x)>n ? n+1 : a[x]+x);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Java bytesToHexString 解析
    Redis 启动警告错误解决
    Jackson
    HttpClient和HttpURLConnection的区别
    (HttpURLConnection)强制转化
    由sqlite在手机上的存储位置,引发的onCreate在哪里执行的小结
    Android数据存储五种方式总结
    Android 操作SQLite基本用法
    Android中SQLite应用详解
    android基础
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10181496.html
Copyright © 2011-2022 走看看