这题让我升华。。还好只重构了一遍


首先我们发现:$n$较小时,整个队伍的形态 跟 $n$ 比较大时的局部是一样的

所以我们预处理出这个队伍的形态,和每一行每个位置的质因子个数的前缀和,$O(nlogn)$,然后每次回答$log(n)$

方法:

1.线性筛,筛出每个数值因子的个数;

2.然后用一个树状数组,维护整个队列中的还存在的数的数量;相当于统计一个数组(设其为$a$)的前缀和,这个数组以自己为下标,存储这个数还存不存在,即$a[x]=1表示x存在,a[x]=0表示x不存在$;刚开始$a$中都为$1$,当某个数$x$被删除时,单点修改$a[x]=0$.

3.查询排名:这里要用到倍增的思路。因为当树状数组的下标$pos==2^k$时,它维护的是$[1,2^k]$的前缀和,所以根据树状数组的思想,可以倍增查找;

4.因为每次查询后都会删一个数,所以查询的实际位置是$fib[i]-已经删去的数的个数,即fib[i]-i+1$

5.最后对于每一个询问,在预处理出的 队伍形态 的数组的第$k$行中,查找编号小于但最接近$n$的那个数数的位置,对应到前缀和数组中的位置就是答案。

但是自己还有个疑问:为何空间开一半就够了。。。自己一直MLE,看了题解才开了一半qwq

PS:bitset比bool 快一些

代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<bitset>
#define R register int
const int N=,K=;
using namespace std;
inline int g() {
R ret=,fix=; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-:fix;
do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret*fix;
}
int c[N+],fib[];
inline int lbt(int x) {return x&-x;}
inline void add(int pos,int vl) {for(;pos<=N;pos+=lbt(pos)) c[pos]+=vl;}
int pri[N/],tot;
short cnt[N+];
bitset<N+> vis;
inline void PRI() {
for(R i=;i<=N;++i) {
if(!vis[i]) pri[++tot]=i,cnt[i]=;
for(R j=;j<=tot&&i*pri[j]<=N;++j) {
vis[i*pri[j]]=true,cnt[i*pri[j]]=cnt[i]+;
if(i%pri[j]==) break;
}
}
}
vector<int> sum[K+],num[K+];
inline int query(int rk) {
R pos=,tot=; for(R t=;t>=;--t)
if(tot+c[pos+(<<t)]<rk) pos+=(<<t),tot+=c[pos];
return pos+;
}
inline void PRE() { PRI(); fib[]=,fib[]=;
for(R i=;i<=;++i) fib[i]=fib[i-]+fib[i-];
for(R i=;i<=N;++i) add(i,); R tot=N;
for(R i=;i<=K;++i) for(R j=;fib[j]-j+<=tot;++j) {
R pos=query(fib[j]-j+); add(pos,-),--tot; //cout<<pos<<" "<<cnt[pos]; putchar('\n');
if(j>=) sum[i].push_back(sum[i][j-]+cnt[pos]);
else sum[i].push_back(cnt[pos]);
num[i].push_back(pos);
}
}
signed main() { PRE(); R t=g();
for(R i=;i<=t;++i) {
R n=g(),k=g(); if(num[k][]>n) {printf("-1\n"); continue;}
R pos=upper_bound(num[k].begin(),num[k].end(),n)-num[k].begin()-;
printf("%d\n",sum[k][pos]);
} //while(1);
}

2019.05.17

Luogu P4901 排队 fib数列+树状数组+倍增的更多相关文章

  1. 【bzoj2819】Nim DFS序+树状数组+倍增LCA

    题目描述 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...

  2. [NOIP2013提高&洛谷P1966]火柴排队 题解(树状数组求逆序对)

    [NOIP2013提高&洛谷P1966]火柴排队 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相 ...

  3. 【BZOJ】1699: [Usaco2007 Jan]Balanced Lineup排队(rmq/树状数组)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1699 我是用树状数组做的..rmq的st的话我就不敲了.. #include <cstdio& ...

  4. 题解报告:Luogu P3368 【模板】树状数组 2(区间修改,单点查询)

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

  5. [luogu]P2657低头一族[树状数组]

    [luogu]P2657 低头一族 题目描述 一群青年人排成一队,用手机互相聊天. 每个人的手机有一个信号接收指标,第i个人的接收指标设为v[i]. 如果位置在x[i]的人要和位置在xj的人聊天,那么 ...

  6. Luogu P3374 【模板】树状数组 1

    真正的模板题. 树状数组的思想很简单(不如说背代码更简单),每个节点记录多个节点的信息(每个点存x&(-x)个). 道理可以参见很多大佬的博客,最后前缀和的思想搞一下就好了.不想说也不会说. ...

  7. bzoj2141: 排队(分块+树状数组)

    块套树为什么会这么快.. 先跑出原序列逆序对. 显然交换两个位置$l,r$,对$[1,l),(r,n]$里的数没有影响,所以只需要考虑$[l,r]$内的数. 设$(l,r)$内的数$a_i$,则按以下 ...

  8. 【Luogu】P2617Dynamic Ranking(树状数组套主席树)

    题目链接 树状数组套主席树有点难懂qwq 不好理解 树状数组套主席树的直观理解应该是:树状数组的每一个节点是一棵主席树. 普通区间修改我们是创建1个线段树,树状数组套主席树的时候我们就创建log个线段 ...

  9. BZOJ 2141 排队(分块+树状数组)

    题意 第一行为一个正整数n,表示小朋友的数量:第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高:第三行为一个正整数m,表示交换操作的次数:以下m行每行包含两个正整数 ...

随机推荐

  1. MySQL 和 InnoDB

    发现一篇总结的很不错的文章,转一下 (原文作者:Draveness   原文链接:https://draveness.me/mysql-innodb) 作为一名开发人员,在日常的工作中会难以避免地接触 ...

  2. 洛谷 P4547 & bzoj 5006 随机二分图 —— 状压DP+期望

    题目:https://www.luogu.org/problemnew/show/P4547 https://www.lydsy.com/JudgeOnline/problem.php?id=5006 ...

  3. Starting MySQL....The server quit without updating PID file错误解决办法

    出现错误:Starting MySQL....The server quit without updating PID file 检查错误文件: /var/lib/mysql/xxxx.err,根据其 ...

  4. spring IOC 注解@Required

    @Required注解适用于bean属性的setter方法,使用@Required的方法必须在xml中填充,负责报错 例如下面的例子中,student中的setAge和setName有@Require ...

  5. puppet插件fact和hiera(puppet自动化系列3)

    四.Fact插件 4.1 使用pluginsync进行发布 这种方法比较特殊,节点factpath目录里除了编写好的rb文件之外,还需要在puppet模块中引用,运行一次之后才会转换成fact.通常在 ...

  6. Scala总结

    Scala总结 ===概述 scala是一门以Java虚拟机(JVM)为目标运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言. scala是纯粹的面向对象的语言.java虽然是面 ...

  7. java基础知识(4)---设计模式

    设计模式:解决问题最行之有效的思想.是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. java中有23种设计模 ...

  8. VisualGDB系列2:VisualGDB对Linux平台的支持特性

    根据VisualGDB官网(https://visualgdb.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指正. 1 复杂问题的直观解决方案 只需要轻点几 ...

  9. python 爬虫 之BeautifulSoup

    BeautifulSoup是一个模块,该模块用于接收一个HTML或XML字符串,然后将其进行格式化,之后便可以使用他提供的方法进行快速查找指定元素,从而使得在HTML或XML中查找指定元素变得简单. ...

  10. linux 下 安装mysql

    安装之前,因为redhat 是yum自带的,但是不能使用,因为要交钱,还要订阅,所以需要卸载,重新安装163提供的yum 在另外一篇文章介绍 yum list mysql* 列出所有关于mysal的安 ...