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;
}

原文地址:https://www.cnblogs.com/youth518/p/13904459.html