题解-bzoj4320 Homework
Problem
Solution
前置技能:分块+线段树+卡常+一点小小的数学知识
考试时A的
这种题无论怎么处理总有瓶颈,套路分块,设\(k\)以下的插入时直接暴力预处理,查询时直接调用;\(k\)以上的插入时不管,查询时线段树查找每个模意义下的区间
核心代码:
if(opt[0]=='A'){
	for(rg int i=1;i<=k;++i)f[i]=min(f[i],x%i);
	update(1,n,1,x);
}
else
	if(x<=k)printf("%d\n",f[x]);
	else {
		int res(inf);
		for(rg int i=0;i<=n;i+=x)
			res=min(res,query(1,n,1,max(1,i),min(i+x-1,n))-i);
		printf("%d\n",res);
	}
考虑到当分界线为\(k\),变量为\(x\)时,插入复杂度为\(O(k)\),查询时复杂度为\(O(1)\)或\(O(\frac nx\log_2n)\leq O(\frac nk\log_2n)\)
如果直接采用大众分块做法(块大小为\(\sqrt n\)),则算法瓶颈为\(O(\sqrt n \log_2n)\),总体复杂度\(O(n\sqrt n\log_2n)\)无法通过此题
考虑算法瓶颈,总体单次复杂度为\(O(k+\frac nk\log_2n)\),利用基本不等式\(a+b\geq 2\sqrt{ab}\),得知总体单次复杂度最小为\(O(2\sqrt{k\cdot \frac nk \log_2n})=O(\sqrt{n\log_2n})\),而满足这个不等式取等的条件是\(a=b\Leftrightarrow k=\frac nk \log_2n\Leftrightarrow k=\sqrt {n\log_2n}\),再考虑上取膜运算和线段树的常数因子影响,取\(k=1732\)时最优
注意,以上并非平均情况下的最优,而是最差情况下的最优(一般情况下\(k=\sqrt n\)的程序甚至更快),也就是说,如果出题人看了你的程序,精心构造数据卡你,\(k=1732\)的程序被卡后是最快的,可以保证复杂度在\(O(n\sqrt {n \log_2 n})\)
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rg register
template <typename _Tp> inline _Tp read(_Tp&x){
	char c11=getchar(),ob=0;x=0;
	while(c11^'-'&&!isdigit(c11))c11=getchar();if(c11=='-')c11=getchar(),ob=1;
	while(isdigit(c11))x=x*10+c11-'0',c11=getchar();if(ob)x=-x;return x;
}
const int N=301000,inf=0x7fffffff;
int f[N],s[N<<2],fc[N];
int Q,k,n=300000;
void pre(){// 1817|1732
	k=1732;
	for(rg int i=1;i<=k;++i)f[i]=inf;
/*	fc[0]=-1;
	for(rg int i=1;i<=n;++i)fc[i]=fc[i>>1]+1;
	double mi=inf,tp;k=1;
	for(rg int i=2;i<=n;++i)
		if((tp=abs(i*i-1.0*n*fc[i]))<1.0*mi)mi=tp,k=i;*/
}
void build(int l,int r,int x){
	s[x]=inf;
	if(l==r)return ;
	int mid(l+r>>1);
	build(l,mid,x<<1);
	build(mid+1,r,x<<1|1);
	return ;
}
inline void update(int l,int r,int x,int ps){
	if(l==r){s[x]=l;return ;}
	int mid(l+r>>1);
	if(ps<=mid)update(l,mid,x<<1,ps);
	else update(mid+1,r,x<<1|1,ps);
	s[x]=min(s[x<<1],s[x<<1|1]);return ;
}
inline int query(int l,int r,int x,int L,int R){
	if(L<=l&&r<=R)return s[x];
	int mid(l+r>>1),res(inf);
	if(L<=mid)res=min(res,query(l,mid,x<<1,L,R));
	if(mid<R)res=min(res,query(mid+1,r,x<<1|1,L,R));
	return res;
}
int main(){
	freopen("f.in","r",stdin);
	freopen("f.out","w",stdout);
	pre();read(Q);
	build(1,n,1);
	char opt[2];int x;
	while(Q--){
		scanf("%s",opt);read(x);
		if(opt[0]=='A'){
			for(rg int i=1;i<=k;++i)f[i]=min(f[i],x%i);
			update(1,n,1,x);
		}
		else
			if(x<=k)printf("%d\n",f[x]);
			else {
				int res(inf);
				for(rg int i=0;i<=n;i+=x)
					res=min(res,query(1,n,1,max(1,i),min(i+x-1,n))-i);
				printf("%d\n",res);
			}
	}return 0;
}
题解-bzoj4320 Homework的更多相关文章
- bzoj4320 homework 题解
		题面链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4320 令M=sqrt(mx),把询问的Y按M 分成两种不同的处理方式. 1.对于> ... 
- BZOJ4320 homework
		Description:给定\(n\)个操作,向集合中加入一个数(保证每个数不同)或者查询集合内\(\text{%Y}\)的最小值 Solution:对于小于\(\sqrt{300000}\)的直接暴 ... 
- 【BZOJ4320】ShangHai2006 Homework 分段+并查集
		[BZOJ4320]ShangHai2006 Homework Description 1:在人物集合 S 中加入一个新的程序员,其代号为 X,保证 X 在当前集合中不存在. 2:在当前的人 ... 
- HDU1789(Doing Homework again)题解
		HDU1789(Doing Homework again)题解 以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定任务分数和其截止日期,每日可完成一任务,输出当罚分尽可能小时 ... 
- 【题解】HDU Homework(倍增)
		[题解]HDU Homework(倍增) 矩阵题一定要多多检查一下是否行列反了... 一百个递推项一定要存101个 说多了都是泪啊 一下午就做了这一道题因为实在是太菜了太久没写这种矩阵的题目... 设 ... 
- Hdoj 1789 Doing Homework again 题解
		Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of h ... 
- [BZOJ4320][ShangHai2006]Homework(根号分治+并查集)
		对于<=sqrt(300000)的询问,对每个模数直接记录结果,每次加入新数时暴力更新每个模数的结果. 对于>sqrt(300000)的询问,枚举倍数,每次查询大于等于这个倍数的最小数是多 ... 
- BZOJ4320 ShangHai2006 Homework(分块+并查集)
		考虑根号分块.对于<√3e5的模数,每加入一个数就暴力更新最小值:对于>√3e5的模数,由于最多被分成√3e5块,查询时对每一块找最小值,这用一些正常的DS显然可以做到log,但不太跑得过 ... 
- 【bzoj4320】【ShangHai2006 Homework】【并查集+离线处理】
		ShangHai2006 Homework Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 918 Solved: 460[Submit][Statu ... 
随机推荐
- redis注册成window服务 标签: redis
			注册服务 redis-server.exe –service-install redis.windows.conf 删除服务 redis-server –service-uninstall 开启服务 ... 
- Git(查看修改记录)
			我们已经成功地添加并提交了一个readme.txt文件,现在,是时候继续工作了,于是,我们继续修改readme.txt文件,改成如下内容: Git is a distributed version c ... 
- Linux 内核里的数据结构:位图(bitmap)
			注: 本文由 LCTT 原创翻译,Linux中国 荣誉推出 Linux 内核中的位数组和位操作 除了不同的基于链式和树的数据结构以外,Linux 内核也为位数组(或称为位图(bitmap))提供了 A ... 
- weblogic每天日志合并shell脚本 [个人记录]【转】【补】
			from RogerZhu modified by King sh logback.rb "/data/logs/" "/tmp/domain" "a ... 
- getResource()和getResourceAsStream以及路径问题【转】【补】
			一 getResource 用JAVA获取文件,听似简单,但对于很多像我这样的新人来说,还是掌握颇浅,用起来感觉颇深,大常最经常用的,就是用JAVA的File类,如要取得c:/test.txt文件,就 ... 
- lasticsearch最佳实践之分片使用优化
			一.遇到的问题 与大多数分布式系统一样,Elasticsearch按照一定的Hash规则把用户数据切分成多个分片,然后打散到不同机器进行存储,从而实现大规模数据的分布式存储. cluster.png ... 
- IQueryable & IEnumberable 区别
			Namespace And Inheritances Relations ? 1 2 3 4 5 6 7 8 9 Namespace: System.Collections [ComVisib ... 
- 深入浅出mybatis之入门使用
			写在前面 mybatis是一个持久层框架,可以支持SQL定制和存储过程,实现数据库记录到Java POJO对象之间的映射. 所以说,mybatis是一个ORM框架. 这个ORM可以通过2种方式实现:x ... 
- for-each 格式
			public class D21LX { public static void main(String arge[]){ fish [] a1=new fish[3]; a1[0] = new fis ... 
- article2pdf (Wordpress plug-in) Multiple vulnerabilities(CVE-2019-1000031, CVE-2019-1010257)
			Product: article2pdf (Wordpress plug-in)Product Website: https://wordpress.org/plugins/article2pdf/A ... 
