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

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 9355  Solved: 4816

    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

    4
    1 2 1 1
    3
    1 1
    2 1 1
    1 1

    Sample Output

    2
    3

    HINT

     

    Source

    树 LCT

    每个位置当成一个结点,维护一棵Link-cut tree

    将代表出界的点0置为根。如果一个点x可以弹跳到另一个点y,就连接x和y;如果从x会弹飞,就连接x和0

    回答询问时,先access(x),看x左子树的size(也就是x的father的数量)就知道需要弹多少次了。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<queue>
      6 using namespace std;
      7 const int mxn=200010;
      8 int read(){
      9     int x=0,f=1;char ch=getchar();
     10     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
     11     while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();}
     12     return x*f;
     13 }
     14 int n,m;
     15 struct node{
     16     int ch[2];
     17     int sz,fa;
     18     bool rt;
     19 }t[mxn];
     20 void init(){
     21     for(int i=1;i<=n;i++){t[i].sz=1;t[i].rt=1;}
     22     return;
     23 }
     24 void pushup(int rt){
     25     t[rt].sz=t[t[rt].ch[0]].sz+t[t[rt].ch[1]].sz+1;
     26     return;
     27 }
     28 void rotate(int x){
     29     int y=t[x].fa;int z=t[y].fa,lc,rc;
     30     if(t[y].ch[0]==x)lc=0;else lc=1; rc=lc^1;
     31     if(t[y].rt){
     32         t[y].rt=0;t[x].rt=1;
     33     }
     34     else t[z].ch[t[z].ch[1]==y]=x;
     35     t[x].fa=z;t[y].ch[lc]=t[x].ch[rc];
     36     t[t[x].ch[rc]].fa=y;t[x].ch[rc]=y;
     37     t[y].fa=x;
     38     pushup(y);
     39     return;
     40 }
     41 void Splay(int x){
     42     while(!t[x].rt){
     43         int y=t[x].fa;int z=t[y].fa;
     44         if(t[y].rt)rotate(x);
     45         else{
     46             if((t[y].ch[0]==x)^(t[z].ch[0]==y))rotate(x);
     47                 else rotate(y);
     48             rotate(x);
     49         }
     50     }
     51     pushup(x);
     52     return;
     53 }
     54 void access(int x){//访问x 
     55     int y=0;
     56     while(x){
     57         Splay(x);
     58         t[t[x].ch[1]].rt=1;t[y].rt=0;//切断x原来的右子树 
     59         t[x].ch[1]=y;//当前点连接被访问点 
     60         pushup(x);
     61         y=x;x=t[x].fa;//上溯 
     62     }
     63 }
     64 void find(int x){
     65     access(x);
     66     Splay(x);
     67 }
     68 void link(int x,int y){
     69     find(x);
     70     t[t[x].ch[0]].fa=0;
     71     t[t[x].ch[0]].rt=1;
     72     t[x].ch[0]=0;
     73     t[x].fa=y;
     74     pushup(x);
     75     return;
     76 }
     77 int main(){
     78     int i,j,k,u,v;
     79     n=read();
     80     init();
     81     for(i=1;i<=n;i++){
     82         k=read();
     83         if(i+k<=n)link(i,i+k);
     84     }
     85     m=read();
     86     while(m--){
     87         k=read();
     88         if(k==1){
     89             u=read()+1;//编号整体+1 
     90             find(u);
     91             printf("%d
    ",t[t[u].ch[0]].sz+1);
     92         }
     93         else{
     94             u=read()+1;k=read();
     95             if(u+k>n)link(u,0);
     96             else link(u,u+k);
     97         }
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    GIT在Linux上的安装和使用简介心得
    Android开发环境使用到工具的认识心得
    Android系统移植与驱动开发心得
    嵌入式Linux的调试技术
    硬件抽象层——HAL
    Linux代码的重用与强行卸载Linux驱动
    控制发光二极管
    详细讲解Linux驱动程序
    搭建测试环境——针对S3C6410开发板
    有了源代码,当然还需要编译喽!!
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6361417.html
Copyright © 2011-2022 走看看