zoukankan      html  css  js  c++  java
  • (分块)Holes CodeForces

    题意

    n(n≤105)个洞排成一条直线,第ii个洞有力量值ai,当一个球掉进洞ii时就会被立刻弹到i+ai,直到超出n。进行m(m105)次操作:

    ·修改第i个洞的力量值ai

    ·在洞xx上放一个球,问该球几次后被哪个洞弹飞出界。

    思路

    分块暴力,每个块内维护两个信息(块内DP可以求出):

    ①从当前位置跳出块内需要跳几次num[i]

    ②从当前块内跳出的下一个位置jump[i]

    修改:

    只需要将修改元素所在块内信息更新一次即可,单次时间复杂O(√n)

    查询:

    由起点i不停往下一个块跳jump[i],并且累计次数num[i],在最后一个块内暴力便利一遍就行了

    #include<iostream>
    #include<algorithm>
    #include<cmath>
     using namespace std;
    const int maxn=1e5+10;
    int n,m,bl,bel[maxn],x,y;
    int a[maxn],num[maxn],jump[maxn];
    void update(int x)
    {
    	int fr=x*bl,to=fr+bl-1;if(to>n) to=n;
    	for(int i=to;i>=fr;i--){
    		if(a[i]+i>to){
    			num[i]=1;
    			jump[i]=a[i]+i;
    		}
    		else{
    			num[i]=num[i+a[i]]+1;
    			jump[i]=jump[i+a[i]];
    		}
    	}
    }
    void query(int x)
    {
    	int ans=0,i,pre;
    	for(i=x;i<=n;i=jump[i])
    		ans+=num[i],pre=i;
    	while(pre+a[pre]<=n)
    		pre+=a[pre];
    	printf("%d %d
    ",pre,ans);
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	int op;
    	for(int i=1;i<=n;i++){
    		scanf("%d",&a[i]);
    		num[i]=0;
    		jump[i]=i;
    	}
    	bl=sqrt(n);
    	for(int i=0;i<=n/bl;i++)
    		update(i);
    	while(m--){
    		scanf("%d",&op);
    		if(op==0){
    			scanf("%d%d",&x,&y);
    			a[x]=y;
    			update(x/bl);
    		}
    		else{
    			scanf("%d",&x);
    			query(x);
    		}
    	}
    	return 0;
    }
    

      

     

     

  • 相关阅读:
    回归模型与房价预测
    朴素贝叶斯应用:垃圾邮件分类
    编程实现朴素贝叶斯分类算法
    朴素贝叶斯分类算法
    K-means算法应用:图片压缩
    第八次作业
    第六次作业
    numpy数据集练习
    第五次作业
    中文词频统计
  • 原文地址:https://www.cnblogs.com/overrate-wsj/p/12170665.html
Copyright © 2011-2022 走看看