zoukankan      html  css  js  c++  java
  • BZOJ 2002: [Hnoi2010]Bounce 弹飞绵羊 分块

    (好吧好吧这是LCT裸题)。。。from RYC's 课件


    然鹅分块大法好。。。

    分成 F(n) 块(至于这个函数怎么写就是你的事了) 块内计算出所有位置在块内能跳的次数cnt,和指向的下一个位置nxt,直接跳到块的末尾,然后进到下一个块;如果跳出块,重新计算cnt和nxt。。。

    (记住编号是0-n-1,要加1(反正我加了QAQ)。。。)

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #define R register int
    using namespace std;
    inline int g() {
        R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix;
        do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix;
    }
    int T,n,m;
    int k[200010],pos[200010],cnt[200010],nxt[200010];
    inline void change(int p,int inc) {
        k[p]=inc;
        for(R i=p;i>=T*(pos[p]-1);--i) {
            if(i+k[i]>min(T*pos[i],n)) cnt[i]=1,nxt[i]=i+k[i];
            else cnt[i]=cnt[i+k[i]]+1,nxt[i]=nxt[i+k[i]];
        }
    }
    inline int query(int p) { R ret=0;
        while(p<=n) ret+=cnt[p],p=nxt[p];
        return ret;
    }
    signed main() {
        n=g(); T=sqrt(n)+1;
        for(R i=1;i<=n;++i) k[i]=g();
        for(R i=1;i<=n;++i) pos[i]=(i-1)/T+1;
        for(R i=n;i>=1;--i) 
            if(i+k[i]>min(T*pos[i],n)) cnt[i]=1,nxt[i]=i+k[i];
            else cnt[i]=cnt[i+k[i]]+1,nxt[i]=nxt[i+k[i]]; 
        m=g(); for(R i=1;i<=m;++i) {
            R k=g(),p=g(),d;
            if(k&1) printf("%d
    ",query(p+1));
            else d=g(),change(p+1,d);
        }
    }

    重拾旧技QAQ 2019.04.23

  • 相关阅读:
    zz java java.nio.ByteBuffer flip
    看到的应用mina做的一个实例
    命令行工具SVN
    ByteBuffer 理解
    Linux命令行下常用svn命令
    三元操作符对null 的处理
    获取最后一个字符串
    C#分割字符串
    学习Silverlight 书籍
    oralce 进行多表同步
  • 原文地址:https://www.cnblogs.com/Jackpei/p/10755533.html
Copyright © 2011-2022 走看看