• BZOJ2002 [HNOI2010]弹飞绵羊


    【问题描述】

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

    【输入格式】

    第一行包含一个整数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

    【输出格式】

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

    【输入样例】

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

    【输出样例】

    2
    3

    正解:LCT

    解题报告:直接用动态树维护,然后在splay里面维护一个子树的大小size就可以了。

      1 #include <iostream>
      2 #include <iomanip>
      3 #include <string>
      4 #include <algorithm>
      5 #include <cmath>
      6 #include <cstring>
      7 #include <cstdlib>
      8 #include <cstdio>
      9 #define RG register
     10 const int N = 300000;
     11  
     12 using namespace std;
     13  
     14 int gi(){
     15     char ch=getchar();int x=0;
     16     while(ch<'0' || ch>'9') ch=getchar();
     17     while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
     18     return x;
     19 }
     20  
     21 int n,m,f[N],fa[N],rev[N],c[N][2],st[N],nx[N],siz[N];
     22  
     23 int isroot(int x){
     24     return c[fa[x]][0]!=x && c[fa[x]][1]!=x;
     25 }
     26  
     27 void pushdown(int x){
     28     if (rev[x]==0) return;
     29     RG int l=c[x][0],r=c[x][1];
     30     rev[x]^=1,rev[l]^=1,rev[r]^=1;
     31     swap(c[x][0],c[x][1]);
     32     return;
     33 }
     34  
     35 void pushsum(int x){
     36     siz[x]=siz[c[x][0]]+siz[c[x][1]]+1;
     37     return;
     38 }
     39  
     40 void rotate(int x){
     41     RG int l,r,y=fa[x],z=fa[y];
     42     if (c[y][0]==x) l=0;
     43     else l=1;r=l^1;
     44     if (!isroot(y))
     45         if (c[z][0]==y) c[z][0]=x;
     46         else c[z][1]=x;
     47     fa[c[x][r]]=y,fa[y]=x,fa[x]=z;
     48     c[y][l]=c[x][r],c[x][r]=y;
     49     pushsum(y),pushsum(x);
     50     return;
     51 }
     52  
     53 void splay(int x){
     54     RG int tot=0;
     55     st[++tot]=x;
     56     for (RG int i=x; !isroot(i); i=fa[i]) st[++tot]=fa[i];
     57     for (RG int i=tot; i; --i) pushdown(st[i]);
     58     while(!isroot(x)){
     59         RG int y=fa[x],z=fa[y];
     60         if (!isroot(y))
     61             if (c[y][0]==x ^ c[z][0]==y) rotate(x);
     62             else rotate(y);
     63         rotate(x);
     64     }
     65     return;
     66 }
     67  
     68 void access(int x){
     69     int t=0;
     70     while(x){
     71         splay(x);
     72         c[x][1]=t;
     73         t=x,x=fa[x];
     74     }
     75     return;
     76 }
     77  
     78 void rever(int x){
     79     access(x),splay(x),rev[x]^=1;
     80     return;
     81 }
     82  
     83 void cut(int x,int y){
     84     rever(x),access(y),splay(y);
     85     c[y][0]=fa[x]=0;
     86     return;
     87 }
     88  
     89 void link(int x,int y){
     90     rever(x);
     91     fa[x]=y;
     92     return;
     93 }
     94  
     95 int main(){
     96     n=gi();RG int s,l,r;siz[n+1]=1;
     97     for (RG int i=1; i<=n; ++i) f[i]=gi(),siz[i]=1;m=gi();
     98     for (RG int i=1; i<=n; ++i) nx[i]=i+f[i]<=n?i+f[i]:n+1;
     99     for (RG int i=1; i<=n; i++) fa[i]=nx[i];
    100     for (RG int i=1; i<=m; i++){
    101         s=gi(),l=gi()+1;
    102         if (s==1){
    103             rever(n+1);
    104             access(l);
    105             splay(l);
    106             printf("%d
    ",siz[c[l][0]]);
    107         }
    108         else{
    109             cut(l,nx[l]);
    110             r=gi(),nx[l]=l+r<=n?l+r:n+1;
    111             link(l,nx[l]);
    112         }
    113     }
    114     return 0;
    115 }
  • 相关阅读:
    【现在还没补的比赛及题解】
    【刷题中】
    【寒假的待填的坑】
    【python】爬虫实践
    【python】vscode python环境配置
    【spring学习笔记二】Bean
    【spring学习笔记一】Ioc控制反转
    【2018CCPC秦皇岛】
    【2018ICPC沈阳】
    【2018ICPC青岛】
  • 原文地址:https://www.cnblogs.com/cjk2001/p/6414309.html
Copyright © 2020-2023  润新知