lightoj 1097 - Lucky Number(线段树)
Lucky numbers are defined by a variation of the well-known sieve of Eratosthenes. Beginning with the natural numbers strike out all even ones, leaving the odd numbers 1, 3, 5, 7, 9, 11, 13, ...The second number is 3, next strike out every third number, leaving 1, 3, 7, 9, 13, ... The third number is 7, next strike out every seventh number and continue this process infinite number of times. The numbers surviving are called lucky numbers. The first few lucky numbers are:
1, 3, 7, 9, 13, 15, 21, 25, 31, 33, ...
In this problem your task is to find the nth lucky number where n is given in input.
Input
Input starts with an integer T (≤ 10000), denoting the number of test cases.
Each case contains an integer n (1 ≤ n ≤ 105).
Output
For each case, print the case number and the nth lucky number.
题意:先给出一个由奇数组成的数列, 1 3 5 7 9 ….. ,现在告诉你, 第i次操作从序列中取出第i个数, 然后每隔a[i]去掉一个数, 问你最后幸存下来的第n个数是多少。
利用线段数暴力操作一遍就行了,由于样例很友善都给出了第100000个数是1429431所以建一个大小为1429431的树就可以了,但是节点大小不要设为
(1429431) << 2这样会ME的。1429431小与2^21所以总结点数小于2^22,大概是1429431的3倍左右就可以了。
至于怎么操作数,要用到前缀和的思想,区间的和表示这区间总公能放多少的点,删掉一个就想这个点的值改为0。具体递归为
if T[p].num < pos (pos - T[p].num , (p<<1)|1) else (pos , p<<1)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int M = 1429431;
struct TnT {
int l , r , sum;
}T[M * 3];
void build(int l , int r , int p) {
int mid = (l + r) >> 1;
T[p].l = l , T[p].r = r;
if(T[p].l == T[p].r) {
T[p].sum = 1;
if(T[p].l % 2 == 0)
T[p].sum = 0;
return ;
}
build(l , mid , p << 1);
build(mid + 1 , r , (p << 1) | 1);
T[p].sum = T[p << 1].sum + T[(p << 1) | 1].sum;
}
void updata(int pos , int p) {
if(T[p].l == T[p].r) {
T[p].sum = 0;
return ;
}
if(T[p << 1].sum < pos) {
updata(pos - T[p << 1].sum , (p << 1) | 1);
}
else {
updata(pos , p << 1);
}
T[p].sum = T[p << 1].sum + T[(p << 1) | 1].sum;
}
int query(int pos , int p) {
if(T[p].l == T[p].r) {
return T[p].l;
}
if(T[p << 1].sum < pos) {
return query(pos - T[p << 1].sum , (p << 1) | 1);
}
else {
return query(pos , p << 1);
}
}
void init() {
build(1 , M , 1);
int gg;
for(int i = 2 ; i <= T[1].sum ; i++) {
gg = query(i , 1);
for(int j = gg ; j <= T[1].sum ; j += (gg - 1)) {
updata(j , 1);
}
}
}
int main()
{
int t;
init();
scanf("%d" , &t);
int ans = 0;
while(t--) {
ans++;
int n;
scanf("%d" , &n);
printf("Case %d: %d\n" , ans , query(n , 1));
}
return 0;
}
lightoj 1097 - Lucky Number(线段树)的更多相关文章
- LightOJ 1097 - Lucky Number 线段树
http://www.lightoj.com/volume_showproblem.php?problem=1097 题意:一个自然数序列,先去掉所有偶数项,在此基础上的序列的第二项为3,则删去所有3 ...
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- HDU-1394 Minimum Inversion Number 线段树+逆序对
仍旧在练习线段树中..这道题一开始没有完全理解搞了一上午,感到了自己的shabi.. Minimum Inversion Number Time Limit: 2000/1000 MS (Java/O ...
- K-th Number 线段树(归并树)+二分查找
K-th Number 题意:给定一个包含n个不同数的数列a1, a2, ..., an 和m个三元组表示的查询.对于每个查询(i, j, k), 输出ai, ai+1, ... ,aj的升序排列中第 ...
- hdu1394Minimum Inversion Number(线段树,求最小逆序数)
Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java ...
- hdu1394(Minimum Inversion Number)线段树
明知道是线段树,却写不出来,搞了半天,戳,没办法,最后还是得去看题解(有待于提高啊啊),想做道题还是难啊. 还是先贴题吧 HDU-1394 Minimum Inversion Number Time ...
- HDU 1394 Minimum Inversion Number(线段树 或 树状数组)
题目大意:给出从 0 到 n-1 的整数序列,A0,A1,A2...An-1.可将该序列的前m( 0 <= m < n )个数移到后面去,组成其他的序列,例如当 m=2 时,得到序列 A2 ...
- K-th Number 线段树的区间第K大
http://poj.org/problem?id=2104 由于这题的时间限制不紧,所以用线段树水一水. 每个节点保存的是一个数组. 就是对应区间排好序的数组. 建树的时间复杂度需要nlogn 然后 ...
- hdu - 1394 Minimum Inversion Number(线段树水题)
http://acm.hdu.edu.cn/showproblem.php?pid=1394 很基础的线段树. 先查询在更新,如果后面的数比前面的数小肯定会查询到前面已经更新过的值,这时候返回的sum ...
随机推荐
- Tomcat源码分析 (一)----- 手写一个web服务器
作为后端开发人员,在实际的工作中我们会非常高频地使用到web服务器.而tomcat作为web服务器领域中举足轻重的一个web框架,又是不能不学习和了解的. tomcat其实是一个web框架,那么其内部 ...
- 想成为顶尖 Java 程序员?请先过了下面这些技术问题。
一.数据结构与算法基础 说一下几种常见的排序算法和分别的复杂度. 用Java写一个冒泡排序算法 描述一下链式存储结构. 如何遍历一棵二叉树? 倒排一个LinkedList. 用Java写一个递归遍历目 ...
- 看完这篇还不清楚Netty的内存管理,那我就哭了!
说明 在学习Netty的时候,ByteBuf随处可见,但是如何高效分配ByteBuf还是很复杂的,Netty的池化内存分配这块还是比较难的,很多人学习过,看过但是还是云里雾里的,本篇文章就是主要来讲解 ...
- 【C++】string::find函数
int vis=a.find(b):从string a开头开始查找第一个遇到的string b,返回string a中所匹配字符串的第一个字符的下标位置,找不到则返回-1. int vis=a.fin ...
- 2月9日 《Java 8实战》读后感
第一部分 基础知识 第3章 Lambda表达式 使用函数式接口 Predicate Consumer Function 第二部分 函数式数据处理 第4章 引入流 第5章 使用流 第6章 用流收集数据 ...
- mpvue微信小程序项目踩坑记录
1.mpvue入门教程, http://mpvue.com/mpvue/quickstart.html # . 先检查下 Node.js 是否安装成功 $ node -v v8.9.0 $ npm - ...
- 写给新手的 Go 开发指南
转眼加入蚂蚁已经三个多月,这期间主要维护一 Go 写的服务器.虽然用的时间不算长,但还是积累了一些心得体会,这里总结归纳一下,供想尝试 Go 的同学参考. 本文会依次介绍 Go 的设计理念.开发环境. ...
- 集合中Iterator迭代器的使用以及实现原理。
collection集合元素通用的获取方式,在取之前先要判断集合中有没有元素,如果有就把这个元素取出来,继续在判断,如果还有就再取出来,一直把集合中的元素全取出来,这种去出方式叫做迭代. 迭代器的作用 ...
- error LNK2001: unresolved external symbol "__declspec(dllimport)
作为C++的小白,出现这个错误,是最头痛的.针对这种问题,我搜了网上的相关答案,很多都是在教Project ---> Settings中改动相关设置.我改了之后,问题依旧没有解决.后面查了这种问 ...
- python所有的内置异常类型汇总
内置异常基类 在 Python 中,所有异常必须为一个派生自 BaseException 的类的实例. 通过子类化创建的两个不相关异常类永远是不等效的,既使它们具有相同的名称. 下列异常主要被用作其他 ...