zoukankan      html  css  js  c++  java
  • 【HNOI2010】弹飞绵羊 题解(分块)

    前言:其实这个题是用LCT做的,但蒟蒻因为太弱了,只会分块QAQ。

    -----------------------------

    题目链接

    题目大意:给定$n$个装置,每个装置有弹力系数$k_i$,即在这个位置上会被弹到$i+k_i$。现在有两个操作:1.修改某个弹力装置的弹力系数。2.问从$x$开始,弹几次后所处位置大于$n$。

    预处理在每个点需要被弹飞的次数$sum[i]$和到达的下一个点$out[i]$。然后进行分块。修改的时候只需要在所在块内的$sum$和$out$即可。

    每次询问和修改的时间复杂度都是$O(sqrt n)$。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=200005;
    int out[maxn],sum[maxn],num[maxn];
    int n,m,block,tot;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    inline int getpos(int x)
    {
        return (x-1)/block+1;
    }
    inline void work(int l,int r)
    {
        for (int i=r;i>=l;i--) 
        {
            if (i+num[i]>getpos(i)*block) sum[i]=1,out[i]=i+num[i];
            else sum[i]=sum[i+num[i]]+1,out[i]=out[i+num[i]];
        }
    }
    int main()
    {
        n=read();block=sqrt(n);
        tot=n/block;if (n%block) tot++;
        for (int i=1;i<=n;i++) num[i]=read();
        work(1,n);
        m=read();
        for (int i=1;i<=m;i++)
        {
            int flag=read(),y=read()+1;
            if (flag==1)
            {
                int ans=sum[y],x=out[y];
                for (int j=getpos(y);j<=tot&&x<=n;j++) ans+=sum[x],x=out[x];
                printf("%d
    ",ans);
            }
            else{
                int z=read();num[y]=z;
                work((getpos(y)-1)*block+1,getpos(y)*block);
            }
        }
        return 0;
    }
  • 相关阅读:
    首页三级菜单显示
    mysql引擎(转)
    nginx配置虚拟主机
    macos10.9 配置nginx,php-fpm
    排序算法 java实现
    Struts清楚session方法
    No result defined for action and result input的错误
    java throw throws
    try catch finally中return语句与非return语句的执行顺序问题
    java操作Excel
  • 原文地址:https://www.cnblogs.com/Invictus-Ocean/p/13293004.html
Copyright © 2011-2022 走看看