题解-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 ...
随机推荐
- 解决CDN传统方法引入Iview icon 不显示问题
因为需要字体文件,可以在github上下载. 将文件下载之后放到fonts文件夹下,fonts文件夹要与Iview.css在同级目录
- js学习总结:DOM节点一(选择器,节点类型)
DOM:document object model 文档对象模型 DOM就是整个HTML文档的关系图谱(代表整个HTML文档),可以理解为下图: 一.查看元素节点 1.document.getElem ...
- HDU 1050(搬椅子 数学)
题意是在一个有 400 个房间的走廊中搬动房间里的椅子,如果两次的路线重叠,就要分两次搬动,如果不重叠,就可以一次搬动. 开始的时候直接当成求线段重叠条数的题,发现这种思路完全是错的,比如 1 - 3 ...
- HDU 1045(炮台安置 DFS)
题意是在 n*n 的方格中进行炮台的安置,炮台不能处于同一行或同一列(类似于八皇后问题),但若是炮台间有墙壁阻挡,则可以同时安置这对炮台.问图中可以安放的最大炮台数目. 用深搜的方法,若此处为空地,则 ...
- PHP7 网络编程(四)signal信号【待】
https://blog.csdn.net/summy_j/article/details/73199069
- springBoot整合mybatis、jsp 或 HTML
springBoot整合mybatis.jsp Spring Boot的主要优点: 1: 为所有Spring开发者更快的入门: 2: 开箱即用,提供各种默认配置来简化项目配置: 3: 内嵌式容器 ...
- python模块之序列化
序列化 什么是序列化 序列化是将字典.列表等数据类型转化成一个字符串的过程 序列化的目的 1. 以某种存储形式使自定义对象持久化(存储) 2. 将对象从一个地方传递到另一个我地方(传输) 3. 使程序 ...
- 细说shiro之一:shiro简介
官网:https://shiro.apache.org/ 一. Shiro是什么Shiro是一个Java平台的开源权限框架,用于认证和访问授权.具体来说,满足对如下元素的支持: 用户,角色,权限(仅仅 ...
- VS 在文件中查找替换界面死掉。
主要问题时一个CopyAndReplace的插件引起的.卸载掉就没问题了.
- 调用waitpid的SIGCHLD信号处理函数
#include <stdio.h> #include <sys/wait.h> void sig_chld(int signo) { pid_t pid; int stat; ...