• Bzoj2002/洛谷P3203 [HNOI2010]弹飞绵羊(分块)


    题面

    Bzoj

    洛谷

    题解

    大力分块,分块大小$sqrt n$,对于每一个元素记一下跳多少次能跳到下一个块,以及跳到下一个块的哪个位置,修改的时候时候只需要更新元素所在的那一块即可,然后询问也是$sqrt n$的模拟。

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using std::min; using std::max;
    using std::swap; using std::sort;
    using std::__gcd;
    typedef long long ll;
    
    template<typename T>
    void read(T &x) {
        int flag = 1; x = 0; char ch = getchar();
        while(ch < '0' || ch > '9') { if(ch == '-') flag = -flag; ch = getchar(); }
        while(ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); x *= flag;
    }
    
    const int N = 2e5 + 10, SN = 450, M = 1e5 + 10;
    int n, m, k[N], x, y, siz, out[N], step[N];
    int bel[N], l[SN], r[SN];
    
    void doit (int L, int R) {
    	for(int i = R; i >= L; --i) {
    		int nxt = i + k[i];
    		if(nxt > R) step[i] = 1, out[i] = nxt;
    		else step[i] = step[nxt] + 1, out[i] = out[nxt];
    	}
    }
    
    int main () {
    #ifdef OFFLINE_JUDGE
        freopen("233.in", "r", stdin);
        freopen("233.out", "w", stdout);
    #endif
    	read(n), siz = sqrt(n);
    	for(int i = 1; i <= n; ++i)
    		read(k[i]), bel[i] = (i - 1) / siz + 1;
    	for(int i = 1; i <= bel[n]; ++i) {
    		l[i] = r[i - 1] + 1, r[i] = min(i * siz, n);
    		doit(l[i], r[i]);
    	}
    	read(m); int opt;
    	while(m--) {
    		read(opt), read(x), ++x;
    		if(opt == 1) {
    			int ret = 0;
    			while(x <= n) ret += step[x], x = out[x];
    			printf("%d
    ", ret);
    		} else read(k[x]), doit(l[bel[x]], r[bel[x]]);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    C语言---堆的实现
    python的matplotlib---雷达图
    python的matplotlib饼状图
    python的matplotlib折线图
    python的matplotlib散点图学习
    python的matplotlib散点图
    C语言---队列(链表实现)
    hadoop集群启动与关闭需要输入密码
    hadoop集群启动时需要输入密码
    C语言---堆栈(链表实现)
  • 原文地址:https://www.cnblogs.com/water-mi/p/10304468.html
Copyright © 2020-2023  润新知