ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ShangHai2006 Homework ZLOJ 练习16 D

2022-07-31 18:31:37  阅读:174  来源: 互联网

标签:ShangHai2006 val 16 int sqrt fa ZLOJ 权值 根号


written on 2022-05-16

开始拿到这题时,很明显是数据结构题,但苦于找不到一个合适的数据结构。

那么对于这样的一道题,正解是根号分治。根号分治,顾名思义,就是将询问对象分成 \(\leq \sqrt n\) 的部分 与 \(\geq \sqrt n\) 的部分,分别进行处理。

对于前一部分,我们可以通过每一次都处理出这一部分的所有答案,时间复杂度为 \(O(n\sqrt n)\) 。

对于后一部分,就要看到根号的性质,即:虽然\(\sqrt n\) ~ \(n\) 很大,但是 \(\frac{n}{\sqrt n}\) 却只有 \(\sqrt n\) 的大小,因此我们可以在这上面做文章。这也就是根号分治的核心所在了。

对于这道题,要求对 \(x\) 取模最小,那么我们可以计算 \(0\) ~ \(x\) ,\(x+1\) ~ \(2x\) ,…… 这些区间内的最小有效权值。注意,这里的最小有效权值指的是,将原数列的权值作为下标后的 最小有数的下标(可以用权值线段树的那个权值加以理解)。

这个子问题的直接想法是用 set ,但是这样总时间复杂度会多上一个 log ,这样就过不了了。因此,这里我们用并查集来辅助操作。

有关并查集维护某集合中大于等于某个数的最小值这样的操作,有几点需要注意:

  1. 初始时,将每个点连向它的下一个点(也就是从一个整数连到大于等于它的最小整数)。

  2. 对于这种操作而言,维护动态变化的集合,一般都是删点的,(具体我也不太清楚为什么,暂留),因此我们的计算方法是离线,倒序处理。

直接贴代码好了,这样的处理方法蛮好理解的,就是有时候好像莫名其妙会爆栈\kk。

#include<bits/stdc++.h>
#define N 300000
using namespace std;
int n,val[N+5],b[N+5];
int fa[N+5],ans[N+5];
bool opt[N+5];
int get(int x){return x==fa[x]?x:fa[x]=get(fa[x]);}
int main()
{
	memset(val,0x3f,sizeof(val));
	scanf("%d",&n);
	int B=sqrt(N);
	for(int i=1;i<=N;i++) fa[i]=i+1;
	fa[N+1]=N+1;
	for(int i=1;i<=n;i++)
	{
		char op[3];
		int x;
		scanf("%s%d",op,&x);
		if(op[0]=='A')
		{
			fa[x]=x,b[i]=-x;
			for(int j=1;j<=B;j++) val[j]=min(val[j],x%j);
		}
		else if(x<=B) ans[i]=val[x],opt[i]=1;
		else b[i]=x,opt[i]=1;
	}
	for(int i=n;i;i--)
	{
		if(!b[i]) continue;
		if(b[i]<0)
		{
			fa[-b[i]]=-b[i]+1;
			continue;
		}
		ans[i]=get(1)%b[i];
		for(int j=b[i];j<=N;j+=b[i])
		{
			int x=get(j);
			if(x==N+1) break;
			ans[i]=min(ans[i],x%b[i]);
		}
	}
	for(int i=1;i<=n;i++) if(opt[i]) printf("%d\n",ans[i]);
}

标签:ShangHai2006,val,16,int,sqrt,fa,ZLOJ,权值,根号
来源: https://www.cnblogs.com/Freshair-qprt/p/16537769.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有