zoukankan      html  css  js  c++  java
  • bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 6521  Solved: 3420
    [Submit][Status][Discuss]

    Description

    某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。

    Input

    第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1,接下来一行有n个正整数,依次为那n个装置的初始弹力系数。第三行有一个正整数m,接下来m行每行至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。对于20%的数据n,m<=10000,对于100%的数据n<=200000,m<=100000

    Output

    对于每个i=1的情况,你都要输出一个需要的步数,占一行。

    Sample Input


    1 2 1 1
    3
    1 1
    2 1 1
    1 1

    Sample Output

    2
    3
     
    题解:
          如果绵羊能从i跳到j,则连一条由i连向j的边,如果能被弹飞,连向n+1,连完之后会形成一个树结构。
      由于可以更改弹力系数,所以树边之间存在断开和连接的操作,就是用动态树来完成。
      1 #include<iostream>
      2 #include<cstdlib>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<vector>
      8 using namespace std;
      9 const int N=200005;
     10 inline int read(){
     11     int x=0,f=1;char ch=getchar();
     12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     13     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
     14     return x*f;
     15 }
     16 int n,m;
     17 int next[N],c[N][2],fa[N],size[N],st[N];
     18 bool rev[N];
     19 bool isroot(int x){
     20     return x!=c[fa[x]][0]&&x!=c[fa[x]][1];
     21 }
     22 void pushup(int x){
     23     size[x]=size[c[x][0]]+size[c[x][1]]+1;
     24 }
     25 void pushdown(int x){
     26     int l=c[x][0],r=c[x][1];
     27     if(rev[x]==true){
     28         rev[x]^=1; rev[l]^=1; rev[r]^=1;
     29         swap(c[x][0],c[x][1]);
     30     }
     31 }
     32 void rotate(int x){
     33     int y=fa[x],z=fa[y],l,r;
     34     if(x==c[y][0]) l=0;else l=1; r=l^1;
     35     if(!isroot(y)){
     36         if(y==c[z][0]) c[z][0]=x;
     37         else c[z][1]=x;
     38     }
     39     fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
     40     c[y][l]=c[x][r]; c[x][r]=y;
     41     pushup(y); pushdown(x);
     42 }
     43 void splay(int x){
     44     int top=0; st[++top]=x;
     45     for(int i=x;isroot(i)==false;i=fa[i]){
     46         st[++top]=fa[i];
     47     }
     48     for(int i=top;i;i--) pushdown(st[i]);
     49     while(!isroot(x)){
     50         int y=fa[x],z=fa[y];
     51         if(!isroot(y)){
     52             if((x==c[y][0]&&y==c[z][0])||(x==c[y][1]&&y==c[z][1])){
     53                 rotate(y),rotate(x);
     54             }
     55             else rotate(x),rotate(x);
     56         }
     57         else rotate(x);
     58     }
     59 }
     60 void access(int x){
     61     int t=0;
     62     while(x!=0){
     63         splay(x);
     64         c[x][1]=t;
     65         t=x; x=fa[x];
     66     }
     67 }
     68 void rever(int x){
     69     access(x); splay(x); rev[x]^=1;
     70 }
     71 void cut(int x,int y){
     72     rever(x); access(y); splay(y); c[y][0]=fa[x]=0;
     73 }
     74 void link(int x,int y){
     75     rever(x); fa[x]=y; splay(x);
     76 }
     77 int main(){
     78     n=read();
     79     for(int i=1;i<=n;i++){
     80           int x=read();
     81         fa[i]=x+i; size[i]=1;
     82         if(fa[i]>n+1) fa[i]=n+1;
     83         next[i]=fa[i];
     84     }
     85     size[n+1]=1;
     86     m=read();
     87     for(int i=1;i<=m;i++){
     88         int f=read();
     89         if(f==1){
     90             rever(n+1);
     91             int x=read(); x++;
     92             access(x);
     93             splay(x);
     94             printf("%d
    ",size[c[x][0]]);
     95         }
     96         else{
     97             int x=read(),y=read(); x++;
     98             int t=min(n+1,x+y);
     99             cut(x,next[x]);
    100             link(x,t);
    101             next[x]=t;
    102         }
    103     }
    104     return 0;
    105 }
       
     
  • 相关阅读:
    泰国行记三:PP岛三天的休闲时光
    泰国行记二:普吉印象
    177. Nth Highest Salary
    176. Second Highest Salary
    175. Combine Two Tables
    Regular Expression Matching
    斐波那契数列
    用两个栈实现队列
    二叉树的下一个节点
    重建二叉树
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/5190048.html
Copyright © 2011-2022 走看看