zoukankan      html  css  js  c++  java
  • 【洛谷P3203】弹飞绵羊【分块】

    题目大意:

    题目链接:https://www.luogu.org/problemnew/show/P3203
    nn个装置,每个装置会把羊往后弹a[i]a[i],要求支持一下操作:

    • 1 x1 x,求从第xx个弹射装置开始需要弹多少次才能把羊弹走。
    • 2 x y2 x y,将第xx个弹射装置的a[i]a[i]改为yy

    思路:

    这道题不说是分块基本就没思路了。
    但是一知道是分块就很好解了。
    我们分成nsqrt n个块,每一个弹射装置维护两个值:

    1. w[i]w[i],弹出这个块之后回到哪一个弹射装置。
    2. s[i]s[i],要多少次才能弹出这个块。

    那么对于每一个操作:

    1. 如果是11操作,那么就从点xx开始,相当于会弹s[x]s[x]次到w[x]w[x],那么再把w[x]w[x]当作xx来继续求。
      每个块最多经过一次,有nsqrt n个块,所以时间复杂度为O(n)O(sqrt n)
    2. 如果是22操作,那么就把这个块暴力重新初始化一遍。这个块最多有nsqrt n个元素,时间复杂度O(n)O(sqrt n)

    总时间复杂度为O(Qn)O(Qsqrt n)。其中QQ为询问个数。


    代码:

    #include <cstdio>
    #include <cmath>
    using namespace std;
    
    const int N=200100;
    int n,Q,T,x,y,L[N],R[N],a[N],w[N],s[N],pos[N];
    
    int ask(int x)
    {
    	int sum=0;
    	while (x<=n)  //没有被弹飞
    	{
    		sum+=s[x];  //次数
    		x=w[x];
    	}
    	return sum;
    }
    
    void change(int x,int y)
    {
    	a[x]=y;
    	for (int i=x;i>=L[pos[x]];i--)  //暴力修改
    		if (i+a[i]>R[pos[x]]) s[i]=1,w[i]=i+a[i];
    			else s[i]=s[i+a[i]]+1,w[i]=w[i+a[i]];
    }
    
    int main()
    {
    	scanf("%d",&n);
    	for (int i=1;i<=n;i++)
    		scanf("%d",&a[i]);
    	T=sqrt(n);
    	for (int i=1;i<=T;i++)
    	{
    		L[i]=R[i-1]+1;
    		R[i]=i*T;
    	}
    	if (R[T]<n)
    	{
    		T++;
    		L[T]=R[T-1]+1;
    		R[T]=n;
    	}
    	for (int i=1;i<=T;i++)
    		for (int j=R[i];j>=L[i];j--)
    		{
    			pos[j]=i;
    			if (j+a[j]>R[i]) s[j]=1,w[j]=j+a[j];
    				else s[j]=s[j+a[j]]+1,w[j]=w[j+a[j]];
    		}
    	scanf("%d",&Q);
    	while (Q--)
    	{
    		scanf("%d",&x);
    		if (x==1)
    		{
    			scanf("%d",&x);
    			printf("%d
    ",ask(x+1));
    		}
    		else
    		{
    			scanf("%d%d",&x,&y);
    			change(x+1,y);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    MySQL迁移升级解决方案
    Python json和simplejson的使用
    ASP.NET使用Memcached高缓存实例的初级介绍
    Spring Cloud Stream在同一通道根据消息内容分发不同的消费逻辑
    JS高级---函数的几个成员
    JS高级---bind方法的使用
    JS高级---bind方法
    JS高级---总结apply和call方法的使用
    JS高级---apply和call都可以改变this的指向
    JS高级---复习
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998443.html
Copyright © 2011-2022 走看看