• BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊


    2002: [Hnoi2010]Bounce 弹飞绵羊

    Time Limit: 10 Sec Memory Limit: 259 MB
    Submit: 12905 Solved: 6578
    [Submit][Status][Discuss]

    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,但网上有很多种不同的做法。。。我是没有用换根直接做。注意编号是0~n-1。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <map>
    #include <string> 
    #include <cmath> 
    #include <sstream>
    #define min(a, b) ((a) < (b) ? (a) : (b))
    #define max(a, b) ((a) > (b) ? (a) : (b))
    #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
    template<class T>
    inline void swap(T &a, T &b)
    {
    	T tmp = a;a = b;b = tmp;
    }
    inline void read(int &x)
    {
        x = 0;char ch = getchar(), c = ch;
        while(ch < '0' || ch > '9') c = ch, ch = getchar();
        while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
        if(c == '-') x = -x;
    }
    const int INF = 0x3f3f3f3f;
    const int MAXN = 200000 + 10;
    int ch[MAXN][2], fa[MAXN], size[MAXN], lazy[MAXN];
    inline int son(int x){return x == ch[fa[x]][1];}
    inline void pushup(int x){size[x] = size[ch[x][0]] + size[ch[x][1]] + 1;}
    inline int isroot(int x){return ch[fa[x]][0] != x && ch[fa[x]][1] != x;}
    void rotate(int x)
    {
    	int y = fa[x], z = fa[y], b = son(x), c = son(y), a = ch[x][!b];
    	if(!isroot(y) && z) ch[z][c] = x; fa[x] = z;
    	if(a) fa[a] = y; ch[y][b] = a;
    	ch[x][!b] = y, fa[y] = x;
    	pushup(y), pushup(x);
    }
    void splay(int x)
    {
    	while(!isroot(x))
    	{
    		int y = fa[x], z = fa[y];
    		if(!isroot(y))
    			if(son(x) == son(y)) rotate(y);
    			else rotate(x);
    		rotate(x);
    	}
    }
    inline void access(int x){for(int y = 0;x;y = x, x = fa[x])splay(x), ch[x][1] = y, pushup(x);}
    inline void link(int x, int y){access(y), splay(y), fa[x] = y, pushup(y);}//把x连到y上,y为父亲 
    inline void cut(int x, int y){access(x), splay(y), fa[x] = ch[y][1] = 0, pushup(x);}//y为x的父亲 
    int n,m,tmp1,tmp2,tmp3,num[MAXN];
    int main()
    {
    	read(n);
    	register int i;
    	for(i = 1;i <= n;++ i) 
    		read(num[i]), fa[i] = min(n + 1, i + num[i]), size[i] = 1;
    	size[n + 1] = 1;
    	read(m);
    	for(i = 1;i <= m;++ i)
    	{
    		read(tmp1), read(tmp2);++ tmp2;
    		if(tmp1 == 1) 
    		{
    			access(tmp2);
    			splay(tmp2);
    			printf("%d
    ", size[ch[tmp2][0]]);
    		}
    		else read(tmp3), cut(tmp2, min(tmp2 + num[tmp2], n + 1)), link(tmp2, min(n + 1, tmp2 + tmp3)), num[tmp2] = tmp3;
    	}
    	return 0;
    }
    
  • 相关阅读:
    Generative Adversarial Nets
    【 剑指Offer 1 】数据结构
    Hopfield神经网络
    LSTMs 长短期记忆网络系列
    【 记忆网络 2 】 End-to-End Memory Network
    MessagePack Java Jackson Dataformat
    MessagePack Java 0.6.X 动态类型
    MessagePack Java 0.6.X 可选字段
    MessagePack Java 0.6.X 不使用注解(annotations)来序列化
    MessagePack Java 0.6.X List, Map 对象的序列化和反序列化
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8418453.html
Copyright © 2020-2023  润新知