zoukankan      html  css  js  c++  java
  • 【HNOI2010】弹飞绵羊

    题面

    https://www.luogu.org/problem/P3203

    题解

    #include<cstdio>
    #include<iostream>
    #define ri register int
    using namespace std;
    
    int f[300050],to[300050],ch[300050][2];
    int s[300050],v[300050];
    int stk[300050];
    bool r[300050];
    int n,m;
    
    bool opt(int x) {
      return ch[f[x]][1]==x;
    }
    
    bool notroot(int x) {
      return ch[f[x]][0]==x || ch[f[x]][1]==x;
    }
    
    void pushup(int x) {
      s[x]=s[ch[x][0]]+s[ch[x][1]]+1;
    }
    
    void pushr(int x) {
      if (!r[x]) return;
      r[x]=false;
      swap(ch[x][0],ch[x][1]); r[ch[x][0]]^=1; r[ch[x][1]]^=1;
    }
    
    void rotate(int x) {
      int y=f[x],z=f[y],s=opt(x);
      if (notroot(y)) ch[z][opt(y)]=x; f[x]=z;
      ch[y][s]=ch[x][1^s]; if (ch[x][1^s]) f[ch[x][1^s]]=y;
      ch[x][1^s]=y; f[y]=x;
      pushup(y); pushup(x);
    }
    
    void splay(int x) {
      int y=x,t=0;
      while(notroot(y)) stk[t++]=y,y=f[y];
      stk[t]=y;
      while (t>=0) pushr(stk[t]),t--;
      while (notroot(x)) {
        if (!notroot(f[x])) rotate(x);
        else {
          if (opt(x)==opt(f[x]) && notroot(f[x])) rotate(f[x]),rotate(x);
          else rotate(x),rotate(x);
        }
      }
    }
    
    void access(int x) {
      int y=0;
      while (x) {
        splay(x);
        ch[x][1]=y;pushup(x);
        y=x;x=f[x];
      }
    }
    
    void makeroot(int x) {
      access(x); splay(x);
      r[x]^=1;
      pushr(x);
    }
    
    int findroot(int x) {
      access(x); splay(x);
      while (ch[x][0]) pushr(x),x=ch[x][0];
      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 a,b,op;
    
    int main(){
      int x;
      scanf("%d",&n);
      for (ri i=1;i<=n;i++) {
        scanf("%d",&x);
        to[i]=min(i+x,n+1);
        link(i,to[i]);
      }
      scanf("%d",&m);
      for (ri i=1;i<=m;i++) {
        scanf("%d",&op);
        if (op==1) {
          scanf("%d",&a);
          a++;
          split(a,n+1);
          pushup(n+1);
          printf("%d
    ",s[n+1]-1);
        }
        else {
          scanf("%d %d",&a,&b);
          a++;
          cut(a,to[a]);
          to[a]=min(a+b,n+1);
          link(a,to[a]);
        }
      }
      return 0;
    }
  • 相关阅读:
    监听键盘弹出 隐藏
    状态栏 设置白色字体
    UITextField 属性详解
    支付宝集成SDK 报错
    UIWebView
    app上传 需要的icon
    百度云推送 pem
    百度地图
    info.plist 属性讲解
    静态库 动态库
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11427217.html
Copyright © 2011-2022 走看看