zoukankan      html  css  js  c++  java
  • CF1032G Chattering ST表+倍增

    题意:

    题面

    分析:

    第一反应是SNOI2017炸弹

    这个题我们一看需要对于每一个数都输出一次答案,也就是说我们需要 (log) 或者 (sqrt n) 的复杂度查询每一个点,那么我们思考一下就发现可以通过倍增处理

    但是由于这个题每个点能扩展的范围是不一样的,所以倍增迭代时我们需要通过区间查询,找到能向左 (向右) 扩展的最远点坐标,也就是说我们需要一个支持区间操作的数据结构,线段树或者ST表都可以,这里给出ST表的代码

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    namespace zzc
    {
    	int read(){
    		int x=0,f=1;char ch=getchar();
    		while(!isdigit(ch)){
    			if(ch=='-') f=-1;ch=getchar();
    		}
    		while(isdigit(ch)){
    			x=(x<<1)+(x<<3)+ch-48;
    			ch=getchar();
    		}
    		return x*f;
    	}
    	
    	const int maxn = 3e5+5;
    	int log[maxn],l[20][maxn],r[20][maxn],a[maxn];
    	int n,ans;
    	
    	struct rmq
    	{
    		int c[maxn][20],val[maxn];
    		int type;
    		
    		int _max(int x,int y)
    		{
    			return (val[x]<val[y]?y:x);
    		}
    		
    		void build(int *a,int n,int flag)
    		{
    			type=flag;
    			for(int i=1;i<=n;i++) c[i][0]=i,val[i]=type*a[i];
    			for(int j=1;j<=log[n];j++)
    			{
    				for(int i=1;i+(1<<j)-1<=n;i++)
    				{
    					c[i][j]=_max(c[i][j-1],c[i+(1<<(j-1))][j-1]);
    				}
    			}
    		}
    		
    		int query(int l,int r)
    		{
    			int k=log[r-l+1];
    			return _max(c[l][k],c[r-(1<<k)+1][k]);
    		}
    		
    	}ql,qr;
    	
    	void work()
    	{
    		n=read();
    		for(int i=2;i<=3*n;i++) log[i]=log[i>>1]+1;
    		for(int i=1;i<=n;i++) a[i]=read(),a[i+2*n]=a[i+n]=a[i];
    		if(n==1)
    		{
    			puts("0");
    			return ;
    		}
    		for(int i=1;i<=3*n;i++) l[0][i]=max(1,i-a[i]),r[0][i]=min(3*n,i+a[i]);
    		for(int i=0;i<=log[3*n];i++) r[i][3*n]=3*n,l[i][1]=1;
    		ql.build(l[0],3*n,-1);qr.build(r[0],3*n,1);
    		for(int j=1;j<=log[3*n];j++)
    		{
    			for(int i=1;i<=3*n;i++)
    			{
    				int posl=ql.query(l[j-1][i],r[j-1][i]);
    				int posr=qr.query(l[j-1][i],r[j-1][i]);
    				l[j][i]=min(l[j-1][posl],l[j-1][posr]);
    				r[j][i]=max(r[j-1][posl],r[j-1][posr]);
    			}
    		}
    		for(int i=n+1;i<=2*n;i++)
    		{
    			int u=i,v=i,ans=0;
    			for(int j=log[3*n];j>=0;j--)
    			{
    				if(max(r[j][u],r[j][v])-min(l[j][u],l[j][v])+1>=n) continue;
    				int tmpu=ql.query(l[j][u],r[j][v]);
    				int tmpv=qr.query(l[j][u],r[j][v]);
    				u=tmpu;v=tmpv;
    				ans+=(1<<j);
    			}
    			ans++;
    			printf("%d ",ans);
    		}
    	}
    
    }
    
    int main()
    {
    	zzc::work();
    	return 0;
    }
    
    
  • 相关阅读:
    让网络更轻盈——网络功能虚拟化技术的现状和未来(中兴通讯)
    服务链(Service Chaining,or Service Function Chaining,SFC,功能服务链)
    中间件(middlebox)
    OpenStack 简介
    数据库系统原理——ER模型与关系模型
    Google 面试
    可扩展性 Scalability
    pay-as-you-go
    Java 自动装箱与拆箱(Autoboxing and unboxing)
    齐次坐标的理解
  • 原文地址:https://www.cnblogs.com/youth518/p/13904459.html
Copyright © 2011-2022 走看看