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

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

    本文作者:ljh2000
    作者博客:http://www.cnblogs.com/ljh2000-jump/
    转载请注明出处,侵权必究,保留最终解释权!

     

    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
     
     
     
    正解:LCT
    解题报告:
      LCT模板题,话说以前一直是用分块写来着...
      我开始一直没弄清楚,为啥有根树可以支持换根操作,后来发现并没有关系,只要在询问的时候先把根换回来再询问就好了…  
      建立一个虚点,每次把查询点access之后,旋转到根,左子树size就是答案了。
     
     
    //It is made by ljh2000
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <ctime>
    #include <vector>
    #include <queue>
    #include <map>
    #include <set>
    #include <string>
    #include <complex>
    using namespace std;
    typedef long long LL;
    typedef long double LB;
    typedef complex<double> C;
    const double pi = acos(-1);
    const int MAXN = 200011;
    int n,m,tr[MAXN][2],tag[MAXN],val[MAXN],father[MAXN];
    int top,stack[MAXN],size[MAXN],next[MAXN]/*必须要分开记录,不然中间会改变*/;
    
    inline int getint(){
        int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
        if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
    }
    
    inline bool isroot(int x){ return (tr[father[x]][0]!=x) && (tr[father[x]][1]!=x); }
    
    inline void update(int x){
    	int l=tr[x][0],r=tr[x][1]; size[x]=1;
    	if(l) size[x]+=size[l]; if(r) size[x]+=size[r];
    }
    
    inline void pushdown(int x){
    	if(tag[x]==0) return ;
    	int l=tr[x][0],r=tr[x][1];
    	tag[l]^=1; tag[r]^=1; swap(tr[x][0],tr[x][1]);
    	tag[x]=0;
    }
    
    inline void rotate(int x){
    	int y=father[x],z=father[y];
    	int l,r; l=(tr[y][1]==x); r=l^1;
    	if(!isroot(y)) tr[z][(tr[z][1]==y)]=x;
    	father[x]=z; father[y]=x;
    	tr[y][l]=tr[x][r]; father[tr[x][r]]=y; tr[x][r]=y;
    	update(y); update(x);
    }
    
    inline void splay(int x){
    	top=0; stack[++top]=x;
    	for(int i=x;!isroot(i);i=father[i]) stack[++top]=father[i];
    	for(int i=top;i>=1;i--) pushdown(stack[i])/*!!!不是top啊!!!*/;
    	int y,z;
    	while(!isroot(x)) {
    		y=father[x]; z=father[y];
    		if(!isroot(y)) {
    			if((tr[z][0]==y) ^ (tr[y][0]==x)) rotate(x);
    			else rotate(y);
    		}
    		rotate(x);
    	}
    }
    
    inline void access(int x){
    	int last=0;
    	while(x){
    		splay(x); tr[x][1]=last;
    		last=x; x=father[x];
    	}
    }
    
    inline void move_to_root(int x){
    	access(x);
    	splay(x);
    	tag[x]^=1;
    }
    
    inline void link(int x,int y){
    	move_to_root(x);
    	father[x]=y; 
    	splay(x);
    }
    
    inline void cut(int x,int y){
    	move_to_root(x);
    	access(y);
    	splay(y);
    	tr[y][0]=father[x]=0;
    }
    
    inline void query(int x){
    	access(x);
    	splay(x);
    	printf("%d
    ",size[tr[x][0]]);
    }
    
    inline void work(){
    	n=getint(); for(int i=1;i<=n;i++) val[i]=getint();
    	for(int i=1;i<=n;i++) {
    		if(i+val[i]>n) father[i]=n+1;
    		else father[i]=i+val[i];
    		next[i]=father[i];
    		//link(i,father[i]);
    	}
    	m=getint(); int type,x,y;
    	while(m--) {
    		type=getint();
    		if(type==1) {
    			move_to_root(n+1);
    			x=getint(); x++;
    			query(x);
    		}
    		else {
    			x=getint(); x++; y=getint();
    			cut(x,next[x]);
    			if(x+y>n) link(x,n+1),next[x]=n+1;
    			else link(x,x+y),next[x]=x+y;
    		}
    	}
    }
    
    int main()
    {
        work();
        return 0;
    }
    

      

  • 相关阅读:
    To select the file to upload we can use the standard HTML input control of type
    Cascading Menu Script using Javascript Explained
    网站首页head区代码规范
    轻松掌握 Java 泛型
    JDK 5.0 中的泛型类型学习
    如何在firefox下获取下列框选中option的text
    是同步方法还是 synchronized 代码? 详解多线程同步规则
    javascript select option对象总结
    Select的动态取值(Text,value),添加,删除。兼容IE,FireFox
    javascript在ie和firefox下的一些差异
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/6475368.html
Copyright © 2011-2022 走看看