• bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊 -- LCT


    2002: [Hnoi2010]Bounce 弹飞绵羊

    Time Limit: 10 Sec  Memory Limit: 259 MB

    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

    LCT入门题

    #include<map>
    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define inf 1000000007
    #define ll long long
    #define N 200010
    inline int rd()
    {
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x*f;
    }
    int n,m;
    int nxt[N],c[N][2],fa[N],sz[N],st[N];
    bool rev[N];
    #define ls c[x][0]
    #define rs c[x][1]
    inline bool isrt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
    inline void pd(int x)
    {
    	if(!rev[x]) return;
    	rev[ls]^=1;rev[rs]^=1;
    	swap(ls,rs);rev[x]=0;
    }
    inline void upd(int x){sz[x]=sz[ls]+sz[rs]+1;}
    void rot(int x)
    {
    	int y=fa[x],z=fa[y],l,r;
    	l=c[y][1]==x;r=l^1;
    	if(!isrt(y)) c[z][c[z][1]==y]=x;
    	fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
    	c[y][l]=c[x][r];c[x][r]=y;
    	upd(x);upd(y);
    }
    void splay(int x)
    {
    	int tt=1,y,z;st[1]=x;
    	for(int i=x;!isrt(i);i=fa[i]) st[++tt]=fa[i];
    	for(int i=tt;i;i--) pd(st[i]);
    	while(!isrt(x))
    	{
    		y=fa[x];z=fa[y];
    		if(!isrt(y))
    		{
    			if(c[y][0]==x^c[z][0]==y) rot(x);
    			else rot(y);
    		}
    		rot(x);
    	}
    } 
    void acc(int x)
    {
    	int t=0;
    	while(x)
    	{
    		splay(x);
    		rs=t;
    		t=x;x=fa[x];
    	}
    }
    void rever(int x)
    {
    	acc(x);splay(x);
    	rev[x]^=1;
    }
    void cut(int x,int y)
    {
    	rever(x);acc(y);
    	splay(y);c[y][0]=fa[x]=0; 
    }
    void link(int x,int y)
    {
    	rever(x);fa[x]=y;
    	splay(x);
    }
    int main()
    {
    	n=rd();
    	for(int i=1,x;i<=n;i++)
    	{
    		x=rd();
    		fa[i]=x+i;sz[i]=1;
    		if(fa[i]>n+1) fa[i]=n+1;
    		nxt[i]=fa[i];
    	}
    	sz[n+1]=1;
    	m=rd();
    	int op,x,y,t;
    	while(m--)
    	{
    		op=rd();
    		if(op==1)
    		{
    			rever(n+1);
    			x=rd()+1;
    			acc(x);splay(x);
    			printf("%d
    ",sz[ls]);
    		}
    		else 
    		{
    			x=rd()+1;y=rd();
    			t=min(n+1,x+y);
    			cut(x,nxt[x]);link(x,t);nxt[x]=t;
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    计算最大公因数
    最大子序列和问题
    C++三大函数:析构函数、复制构造函数和operator=
    C++函数返回值传递
    C++动态内存分配
    Halcon Assistants
    网格细分算法
    HDevelop Guide
    MeshLab
    point cloud registration
  • 原文地址:https://www.cnblogs.com/lkhll/p/8028144.html
Copyright © 2020-2023  润新知