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

    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。

    Output

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

    Sample Input

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

    Sample Output

    2
    3

    HINT

    对于20%的数据n,m<=10000,
    对于100%的数据n<=200000,m<=100000




    这道题本是一道LCT的题,但用分块就可以过了。。。

    分块大法好!

    我们对于每一个位置都维护两个信息:
    1、跳出其所在块需要的步数(step)
    2、跳出其所在块后跳到的位置(where)
    询问的话就不断地跳并累加答案。
    修改的话就暴力重构当先点到其所在块的左端点的信息。
    这两个操作都可以在根号时间做完。
    上标:

    #include<cstdio>
    #include<cmath>
    #define N 200010
    using namespace std;
    struct node{int step,where;}b[N];
    int n,m,a[N],bl[N],l[N],r[N],st;
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    void init()
    {
    	for (int i=1;i<=bl[n];i++)
    		for (int j=r[i];j>=l[i];j--)
    			if (j+a[j]>r[i]) b[j]=(node){1,j+a[j]};
    			else b[j]=(node){b[j+a[j]].step+1,b[j+a[j]].where};
    }
    
    void query(int x)
    {
    	int s=0;
    	for (int i=x;i<=n;i=b[i].where) s+=b[i].step;
    	printf("%d
    ",s);
    }
    
    void change(int x)
    {
    	for (int i=x;i>=l[bl[x]];i--)
    		if (i+a[i]>r[bl[x]]) b[i]=(node){1,i+a[i]};
    		else b[i]=(node){b[i+a[i]].step+1,b[i+a[i]].where};
    }
    
    int main()
    {
    	freopen("2002.in","r",stdin);
    	freopen("2002.out","w",stdout);
    	n=read(),st=sqrt(n);
    	for (int i=1;i<=n;i++)
    	{
    		a[i]=read(),bl[i]=(i-1)/st+1;
    		if (!l[bl[i]]) l[bl[i]]=i;
    		r[bl[i]]=i;
    	}
    	init();
    	m=read();
    	for (int i=1,tt,x,y;i<=m;i++)
    	{
    		tt=read();
    		if (tt==1) x=read()+1,query(x);
    		else x=read()+1,a[x]=read(),change(x);
    	}
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    Git命令大全
    window系统查看端口被哪个进程占用了
    字体大小自适应纯css解决方案
    CSS3的rem设置字体大小
    javascript同名变量
    西部数码云服务器手记
    十年,站酷已成设计论坛霸主,博客园却成无兵之将
    PHP的性能大坑--strtotime函数
    csv表格处理(上)-- JS 与 PHP 协作导入导出
    致互联网--那些我浅尝则止的昙花
  • 原文地址:https://www.cnblogs.com/jz929/p/11817567.html
Copyright © 2011-2022 走看看