zoukankan      html  css  js  c++  java
  • P3203 弹飞绵羊-分块

    P3203 弹飞绵羊-分块

    观察数据范围,发现可以分块。只需要处理每个点跳出所在块后的位置和次数即可。目的是为了加速查询并降低修改复杂度。

    对于修改,重构整个块内信息即可。

    时间复杂度正确的一批

    具体实现也挺简单。注意重构时从后往前贡献即可。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    inline int read(){
    	int w=0,x=0;char c=getchar();
    	while(!isdigit(c))w|=c=='-',c=getchar();
    	while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
    	return w?-x:x;
    }
    namespace star
    {
    	const int maxn=2e5+10;
    	int n,N,out[maxn],cos[maxn],a[maxn],belong[maxn],l[maxn],r[maxn];
    	void sudo(int l,int r){for(int i=r;i>=l;i--)if(i+a[i]>n or belong[i+a[i]]!=belong[i])out[i]=i+a[i],cos[i]=1;else out[i]=out[i+a[i]],cos[i]=1+cos[i+a[i]];}
    	inline void work(){
    		n=read();
    		N=sqrt(n);
    		for(int i=1;i<=n;i++)
    			belong[i]=(i-1)/N+1;
    		for(int i=1;i<=n;i++){
    			if(!l[belong[i]])l[belong[i]]=i;
    			r[belong[i]]=i;
    		}
    		for(int i=1;i<=n;i++)a[i]=read();
    		sudo(1,n);
    		int q=read();
    		while(q--){
    			if(read()==1){
    				int sum=0,pos=read()+1;
    				while(pos<=n)sum+=cos[pos],pos=out[pos];
    				printf("%d
    ",sum);
    			}else{
    				int pos=read()+1;
    				a[pos]=read();
    				sudo(l[belong[pos]],r[belong[pos]]);
    			}
    		}
    	}
    }
    signed main(){
    	star::work();
    	return 0;
    }
    

    那我要是想知道最后弹飞前的点在哪呢?

    我们只需要在重构的时候记录一下从哪来的就好了。

    双倍经验:CF13E

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    inline int read(){
    	int w=0,x=0;char c=getchar();
    	while(!isdigit(c))w|=c=='-',c=getchar();
    	while(isdigit(c))x=(x<<3)+(x<<1)+(c^48),c=getchar();
    	return w?-x:x;
    }
    namespace star
    {
    	const int maxn=2e5+10;
    	int n,N,out[maxn],last[maxn],cos[maxn],a[maxn],belong[maxn],l[maxn],r[maxn];
    	void sudo(int l,int r){for(int i=r;i>=l;i--)if(i+a[i]>min(n,r))out[i]=i+a[i],last[i]=i,cos[i]=1;else out[i]=out[i+a[i]],last[i]=last[i+a[i]],cos[i]=1+cos[i+a[i]];}
    	inline void work(){
    		n=read();
    		int q=read();
    		N=sqrt(n);
    		for(int i=1;i<=n;i++)
    			belong[i]=(i-1)/N+1;
    		for(int i=1;i<=n;i++){
    			if(!l[belong[i]])l[belong[i]]=i;
    			r[belong[i]]=i;
    		}
    		for(int i=1;i<=n;i++)a[i]=read();
    		for(int i=1;i<=belong[n];i++)sudo(l[i],r[i]);
    		while(q--){
    			if(read()==1){
    				int sum,pos,lpos;
    				sum=0,pos=lpos=read();
    				while(pos<=n)sum+=cos[pos],lpos=last[pos],pos=out[pos];
    				printf("%d %d
    ",lpos,sum);
    			}else{
    				int pos=read();
    				a[pos]=read();
    				sudo(l[belong[pos]],r[belong[pos]]);
    			}
    		}
    	}
    }
    signed main(){
    	star::work();
    	return 0;
    }
    
  • 相关阅读:
    苹果一体机发射Wi-Fi
    iphone 屏蔽系统自动更新,消除设置上的小红点
    data parameter is nil 异常处理
    copy与mutableCopy的区别总结
    java axis2 webservice
    mysql 远程 ip访问
    mysql 存储过程小问题
    mysql游标错误
    is not writable or has an invalid setter method错误的解决
    Struts2中关于"There is no Action mapped for namespace / and action name"的总结
  • 原文地址:https://www.cnblogs.com/BrotherHood/p/13775714.html
Copyright © 2011-2022 走看看