zoukankan      html  css  js  c++  java
  • [BZOJ2002] [Hnoi2010] Bounce 弹飞绵羊 (LCT)

    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

    Solution

      每个点和可以到达的点连一条边,支持动态链上查询,LCT大法好

      用和splay一样的方法维护子树大小siz即可。

      感谢Ngshily大爷的版子!!!

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 struct LCT
      4 {
      5     int c[2], fa, rev, siz;
      6     int& operator [] (int i)
      7     {
      8         return c[i];
      9     }
     10 }a[200005];
     11 int sta[200005], top, nxt[200005];
     12  
     13 void scanf(int *x)
     14 {
     15     char ch = getchar();
     16     *x = 0;
     17     while(ch < '0' || ch > '9')
     18         ch = getchar();
     19     while(ch >= '0' && ch <= '9')
     20         *x = *x * 10 + ch - 48, ch = getchar();
     21 }
     22  
     23 void push_up(int k)
     24 {
     25     a[k].siz = a[a[k][0]].siz + a[a[k][1]].siz + 1;
     26 }
     27  
     28 void push_down(int k)
     29 {
     30     if(a[k].rev)
     31     {
     32         a[a[k][0]].rev ^= 1, a[a[k][1]].rev ^= 1;
     33         swap(a[k][0], a[k][1]), a[k].rev = 0;
     34     }
     35 }
     36  
     37 bool isroot(int x)
     38 {
     39     return a[a[x].fa][0] != x && a[a[x].fa][1] != x;
     40 }
     41  
     42 void rotate(int x)
     43 {
     44     int y = a[x].fa, z = a[y].fa;
     45     int dy = a[y][1] == x, dz = a[z][1] == y;
     46     if(!isroot(y)) a[z][dz] = x;
     47     a[y][dy] = a[x][dy ^ 1], a[a[x][dy ^ 1]].fa = y;
     48     a[x][dy ^ 1] = y, a[y].fa = x, a[x].fa = z;
     49     push_up(y);
     50 }
     51  
     52 void splay(int x)
     53 {
     54     sta[top = 1] = x;
     55     for(int i = x; !isroot(i); i = a[i].fa)
     56         sta[++top] = a[i].fa;
     57     while(top)
     58         push_down(sta[top--]);
     59     while(!isroot(x))
     60     {
     61         int y = a[x].fa, z = a[y].fa;
     62         if(!isroot(y))
     63             if(a[y][1] == x ^ a[z][1] == y) rotate(x);
     64             else rotate(y);
     65         rotate(x);
     66     }
     67     push_up(x);
     68 }
     69  
     70 void access(int x)
     71 {
     72     for(int i = 0; x; x = a[x].fa)
     73         splay(x), a[x][1] = i, i = x;
     74 }
     75  
     76 void make_root(int x)
     77 {
     78     access(x), splay(x), a[x].rev ^= 1;
     79 }
     80  
     81 int find_root(int x)
     82 {
     83     access(x), splay(x);
     84     while(a[x][0])
     85         x = a[x][0];
     86     return x;
     87 }
     88  
     89 void link(int x, int y)
     90 {
     91     make_root(x), a[x].fa = y;
     92 }
     93  
     94 void cut(int x, int y)
     95 {
     96     make_root(x), access(y), splay(y), a[y][0] = a[x].fa = 0;
     97 }
     98  
     99 int main()
    100 {
    101     int n, m, x, y, op;
    102     scanf(&n);
    103     for(int i = 1; i <= n; i++)
    104     {
    105         scanf(&x), a[i].siz = 1;
    106         a[i].fa = nxt[i] = min(i + x, n + 1);
    107     }
    108     scanf(&m), a[n + 1].siz = 1;
    109     while(m--)
    110     {
    111         scanf(&op), scanf(&x), x++;
    112         if(op == 1)
    113         {
    114             make_root(n + 1), access(x), splay(x);
    115             printf("%d
    ", a[x].siz - 1);
    116         }
    117         else
    118         {
    119             scanf(&y), cut(nxt[x], x);
    120             nxt[x] = min(x + y, n + 1);
    121             link(nxt[x], x);
    122         }
    123     }
    124     return 0;
    125 }
    View Code
  • 相关阅读:
    Discuz!NT 系统架构分析
    jquery pager
    Nhibernate分页方法
    Discuz nt模板机制
    WTclient创建OPC client方法
    OPC
    Regular Expressions in Java
    How to use VS to manipulate Access
    OPC客户端设计
    How to use VS to manipulate Excel使用MFC读写Excel
  • 原文地址:https://www.cnblogs.com/CtrlCV/p/5370209.html
Copyright © 2011-2022 走看看