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

    2002: [Hnoi2010]Bounce 弹飞绵羊

    Time Limit: 10 Sec  Memory Limit: 259 MB
    Submit: 9071  Solved: 4652
    [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

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

    Sample Output

    2
    3

    HINT

     

    Source

     
    [Submit][Status][Discuss]

    将跳转看成边的关系,易知这些转移边形成一棵树。如果以“弹出去”这个状态为根节点,从一个点出发的步数可以转换为深度,或者说是从根节点到这个点的距离。改变一个点的系数,可以视为改变一个点的父节点,但是其子树不会受到影响。显然是个LCT模板题,第一次写还有些许不懂,大体是从这位前辈的blog里学的。

      1 VAR 
      2     n : longint;
      3     m : longint;
      4     siz : array[-1..200005] of longint;
      5     fat : array[-1..200005] of longint;
      6     rot : array[-1..200005] of boolean;
      7     son : array[-1..200005,0..2] of longint;
      8 
      9 PROCEDURE update(t : longint);
     10 begin  
     11     siz[t]:=siz[son[t,0]]+siz[son[t,1]]+1;
     12 end;
     13 
     14 PROCEDURE ltrotate(x : longint);
     15 var
     16     y : longint;
     17 begin
     18     y:=son[x,1];
     19     son[x,1]:=son[y,0];
     20     fat[son[x,1]]:=x;
     21     son[y,0]:=x;
     22     if x=son[fat[x],0] then
     23         son[fat[x],0]:=y
     24     else if x=son[fat[x],1] then
     25         son[fat[x],1]:=y;
     26     fat[y]:=fat[x];
     27     fat[x]:=y;
     28     rot[y]:=rot[x] xor rot[y];
     29     rot[x]:=rot[x] xor rot[y];
     30     update(x);
     31     update(y);
     32 end;
     33 
     34 PROCEDURE rtrotate(x : longint);
     35 var 
     36     y : longint;
     37 begin
     38     y:=son[x,0];
     39     son[x,0]:=son[y,1];
     40     fat[son[x,0]]:=x;
     41     son[y,1]:=x;
     42     if x=son[fat[x],0] then
     43         son[fat[x],0]:=y
     44     else if x=son[fat[x],1] then
     45         son[fat[x],1]:=y;
     46     fat[y]:=fat[x];
     47     fat[x]:=y;
     48     rot[y]:=rot[x] xor rot[y];
     49     rot[x]:=rot[x] xor rot[y];
     50     update(x);
     51     update(y);
     52 end;
     53 
     54 PROCEDURE splay(x : longint);
     55 begin
     56     while not rot[x] do
     57         if x=son[fat[x],1] then
     58             ltrotate(fat[x])
     59         else
     60             rtrotate(fat[x]);
     61 end;
     62 
     63 PROCEDURE access(x : longint);
     64 var 
     65     y : longint;
     66 begin
     67     splay(x);
     68     while fat[x]<>0 do
     69     begin
     70         y:=fat[x];
     71         splay(y);
     72         rot[son[y,1]]:=true;
     73         rot[x]:=false;
     74         son[y,1]:=x;
     75         update(y);
     76         splay(x);
     77     end;
     78 end;
     79 
     80 PROCEDURE main;
     81 var
     82     i, x, y, z : longint;
     83 begin
     84     read(n);
     85 
     86     for i:=1 to n do
     87     begin
     88         read(fat[i]);
     89         fat[i]:=fat[i]+i;
     90         if fat[i]>n then
     91             fat[i]:=n+1;
     92     end;
     93 
     94     for i:=1 to n+1 do
     95     begin
     96         siz[i]:=1;
     97         rot[i]:=true;
     98     end;
     99 
    100     read(m);
    101 
    102     for i:=1 to m do
    103     begin
    104         read(x);
    105         if x=1 then
    106         begin
    107             read(y);
    108             inc(y);
    109             access(y);
    110             writeln(siz[son[y,0]]);
    111         end
    112         else 
    113         begin
    114             read(y,z);
    115             inc(y);
    116             splay(y);
    117             fat[son[y,0]]:=fat[y];
    118             rot[son[y,0]]:=true;
    119             son[y,0]:=0;
    120             siz[y]:=siz[son[y,1]]+1;
    121             fat[y]:=y+z;
    122             if fat[y]>n then
    123                 fat[y]:=n+1;
    124         end;
    125     end;
    126 end;
    127 
    128 BEGIN
    129     main;
    130 END.
      1 #include <bits/stdc++.h>
      2 
      3 #define fread_siz 1024
      4 
      5 inline int get_c(void)
      6 {
      7     static char buf[fread_siz];
      8     static char *head = buf + fread_siz;
      9     static char *tail = buf + fread_siz;
     10 
     11     if (head == tail)
     12         fread(head = buf, 1, fread_siz, stdin);
     13 
     14     return *head++;
     15 }
     16 
     17 inline int get_i(void)
     18 {
     19     register int ret = 0;
     20     register int neg = false;
     21     register int bit = get_c();
     22 
     23     for (; bit < 48; bit = get_c())
     24         if (bit == '-')neg ^= true;
     25 
     26     for (; bit > 47; bit = get_c())
     27         ret = ret * 10 + bit - 48;
     28 
     29     return neg ? -ret : ret;
     30 }
     31 
     32 template <class T>
     33 inline T min(T a, T b)
     34 {
     35     return a < b ? a : b;
     36 }
     37 
     38 const int N = 200005;
     39 
     40 int n, m;
     41 int root[N];
     42 int lson[N];
     43 int rson[N];
     44 int size[N];
     45 int father[N];
     46 
     47 inline void update(int t)
     48 {
     49     size[t] = size[lson[t]] + size[rson[t]] + 1;
     50 }
     51 
     52 inline void rotateLeft(int t)
     53 {
     54     int r = rson[t];
     55     rson[t] = lson[r];
     56     father[rson[t]] = t;
     57     lson[r] = t;
     58     if (t == lson[father[t]])
     59         lson[father[t]] = r;
     60     else if (t == rson[father[t]])
     61         rson[father[t]] = r;
     62     father[r] = father[t];
     63     father[t] = r;
     64     update(t);
     65     update(r);
     66     root[r] ^= root[t];
     67     root[t] ^= root[r];
     68 }
     69 
     70 inline void rotateRight(int t)
     71 {
     72     int l = lson[t];
     73     lson[t] = rson[l];
     74     father[lson[t]] = t;
     75     rson[l] = t;
     76     if (t == lson[father[t]])
     77         lson[father[t]] = l;
     78     else if (t == rson[father[t]])
     79         rson[father[t]] = l;
     80     father[l] = father[t];
     81     father[t] = l;
     82     update(t);
     83     update(l);
     84     root[l] ^= root[t];
     85     root[t] ^= root[l];
     86 }
     87 
     88 inline void splay(int t)
     89 {
     90     while (!root[t])
     91     {
     92         if (t == lson[father[t]])
     93             rotateRight(father[t]);
     94         else
     95             rotateLeft(father[t]);
     96     }
     97 }
     98 
     99 inline void access(int t)
    100 {
    101     splay(t);
    102     
    103     while (father[t])
    104     {
    105         int f = father[t];
    106         splay(f);
    107         root[rson[f]] = 1;
    108         root[t] = 0;
    109         rson[f] = t;
    110         update(f);
    111         splay(t);
    112     }
    113 }
    114 
    115 inline void cut(int t)
    116 {
    117     splay(t);
    118     root[lson[t]] = 1;
    119     father[lson[t]] = father[t];
    120     lson[t] = 0;
    121     update(t);
    122 }
    123 
    124 signed main(void)
    125 {
    126     n = get_i();
    127     
    128     for (int i = 1; i <= n; ++i)
    129         father[i] = min(get_i() + i, n + 1);
    130     
    131     for (int i = 1; i <= n + 1; ++i)
    132         size[i] = root[i] = 1;
    133         
    134     m = get_i();
    135     
    136     for (int i = 1; i <= m; ++i)
    137     {
    138         int x = get_i(), y, z;
    139         if (x == 1)
    140         {
    141             y = get_i() + 1; access(y);
    142             printf("%d
    ", size[lson[y]]);
    143         }
    144         else
    145         {
    146             y = get_i() + 1; z = get_i();
    147             cut(y); father[y] = min(n + 1, y + z);
    148         }
    149     }
    150 }

    @Author: YouSiki

  • 相关阅读:
    .37-浅析webpack源码之事件流make(4)
    .36-浅析webpack源码之Parser类
    .35-浅析webpack源码之babel-loader入口文件路径读取
    .34-浅析webpack源码之事件流make(3)
    浅探element-ui2组件源码之upload
    .33-浅析webpack源码之doResolve事件流(5)
    .32-浅析webpack源码之doResolve事件流(4)
    .31-浅析webpack源码之doResolve事件流(3)
    .30-浅析webpack源码之doResolve事件流(2)
    windows server 2016 支持多用户远程登录
  • 原文地址:https://www.cnblogs.com/yousiki/p/6226138.html
Copyright © 2011-2022 走看看