Problem

bzoj4320

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的更多相关文章

  1. bzoj4320 homework 题解

    题面链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4320 令M=sqrt(mx),把询问的Y按M 分成两种不同的处理方式. 1.对于> ...

  2. BZOJ4320 homework

    Description:给定\(n\)个操作,向集合中加入一个数(保证每个数不同)或者查询集合内\(\text{%Y}\)的最小值 Solution:对于小于\(\sqrt{300000}\)的直接暴 ...

  3. 【BZOJ4320】ShangHai2006 Homework 分段+并查集

    [BZOJ4320]ShangHai2006 Homework Description   1:在人物集合 S 中加入一个新的程序员,其代号为 X,保证 X 在当前集合中不存在.    2:在当前的人 ...

  4. HDU1789(Doing Homework again)题解

    HDU1789(Doing Homework again)题解 以防万一,题目原文和链接均附在文末.那么先是题目分析: [一句话题意] 给定任务分数和其截止日期,每日可完成一任务,输出当罚分尽可能小时 ...

  5. 【题解】HDU Homework(倍增)

    [题解]HDU Homework(倍增) 矩阵题一定要多多检查一下是否行列反了... 一百个递推项一定要存101个 说多了都是泪啊 一下午就做了这一道题因为实在是太菜了太久没写这种矩阵的题目... 设 ...

  6. 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 ...

  7. [BZOJ4320][ShangHai2006]Homework(根号分治+并查集)

    对于<=sqrt(300000)的询问,对每个模数直接记录结果,每次加入新数时暴力更新每个模数的结果. 对于>sqrt(300000)的询问,枚举倍数,每次查询大于等于这个倍数的最小数是多 ...

  8. BZOJ4320 ShangHai2006 Homework(分块+并查集)

    考虑根号分块.对于<√3e5的模数,每加入一个数就暴力更新最小值:对于>√3e5的模数,由于最多被分成√3e5块,查询时对每一块找最小值,这用一些正常的DS显然可以做到log,但不太跑得过 ...

  9. 【bzoj4320】【ShangHai2006 Homework】【并查集+离线处理】

    ShangHai2006 Homework Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 918  Solved: 460[Submit][Statu ...

随机推荐

  1. 【MSSQL】SQL Server的日期和时间类型

    参考:SQL Server的日期和时间类型 SQL Server使用 Date 表示日期,time表示时间,使用datetime和datetime2表示日期和时间. 1.秒的精度 秒的精度是指TSQL ...

  2. Dubbo管控台安装(zookeeper单机版)

    1. zookeeper安装(单机版):http://www.cnblogs.com/wangfajun/p/5251159.html  √ 注意:我这里的dubbo-admin.war是2.5.3版 ...

  3. golang channle 管道

    管道的使用介绍 现在要计算 1-N 的各个数的阶乘,并且把各个数的阶乘放入到 map 中.最后显示出来.要求使用 goroutine 完成 package main import ( "fm ...

  4. windows安装gitblit服务端

    由于windows下没有gitlab之类的工具,只有很久没有更新的gitblit 下载Gitblit, 下载地址:http://www.gitblit.com/ 很长时间没有更新了,在没有linux环 ...

  5. ES学习之分片路由

    本文主要内容: 1.路由一个文档到一个分片 2.新建.索引和删除请求 3.取回单个文档 4.局部单个文档 5.多文档模式 6.理解一下ES深度分页(from-size)的劣势 路由一个文档到一个分片 ...

  6. Python高性能编程

    一.进程池和线程池 1.串行 import time import requests url_lists = [ 'http://www.baidu.com', 'http://fanyi.baidu ...

  7. 细说log4j之概述

    log4j官网:https://logging.apache.org/ log4j目前存在2个版本:log4j 1.x 和log4j 2.x,目前官方主推2.x版本(log4j 1.x已于2015.0 ...

  8. 对空间数据(Shape)重新排序

    打开ArcToolBox,数据管理工具->常规(General)->排序

  9. 使用 CROSS APPLY 与 OUTER APPLY 连接查询

    Ø  前言 日常开发中遇到多表查询时,首先会想到 INNER JOIN 或 LEFT OUTER JOIN 等等,但是这两种查询有时候不能满足需求.比如,左表一条关联右表多条记录时,我需要控制右表的某 ...

  10. git 完全讲解 无废话,包含在myeclipse中使用,包括解决冲突

    Git 1. Git简介 1.1 git是什么 1.1.1概念 Git:git是一款开源的分布式的版本控制软件 Github:是一个基于git的面向开源及私有软件项目的托管平台 因仅支持git 作为唯 ...