题解-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 ...
随机推荐
- python 函数动态参数,名称空间,global,nonlocal
##################################总结######################################动态参数 *args:位置参数动态传参,接收到的是元 ...
- Hadoop记录-hive merge小文件
1. Map输入合并小文件对应参数:set mapred.max.split.size=256000000; #每个Map最大输入大小set mapred.min.split.size.per.no ...
- C#设计模式(1)——简单工厂模式
1.什么是简单工厂 现实中的工厂负责生产产品,顾名思义,编程中的简单工厂就是一个生产对象的类,它的主要作用是创建具体的产品类实例.我们以一个生产鼠标为例来分析简单工厂的作用,鼠标有两种:戴尔鼠标和惠普 ...
- Accord.NET Framework 介绍
阅读目录 1.基本功能与介绍 Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET ...
- Django之组件--中间件
中间件 中间件是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出.因为改变的是全局,所以需要谨慎实用,用不好会影响到性能 自定义中间 ...
- golang goroutine
goroutine-介绍 1)进程就是程序程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位2)线程是进程的一个执行实例,是程序执行的最小单元,它是比进程更小的能独立运行的基本单位.3 ...
- @CrossOrigin注解与跨域访问
在Controller中看到@CrossOrigin ,这是什么?有什么用?为什么要用? what? @CrossOrigin是用来处理跨域请求的注解 先来说一下什么是跨域: (站在巨人的肩膀上) 跨 ...
- 【移动端】300ms延迟以及点透事件原因以及解决方案
产生原因 移动端会有双击缩放的这个操作,因此浏览器在click之后要等待300ms,看用户有没有下一次点击,也就是这次操作是不是双击 说完移动端点击300ms延迟的问题,还不得不提一下移动端点击穿透的 ...
- 完全使用UDP登录Linux
===============Mosh 登录器========================================= == 针对TCP被某些防火墙阻断的Linux机器, 该程序可以让你不使 ...
- Retrofit GreenDao开发中遇到的坑
持续更新中1.使用@FormUrlEncoded的话,服务端需要使用Request.Form,如果不使用@FormUrlEncoded本地需要由 @FieldMap Map<String, Ob ...