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;
}

最新文章

  1. input在标签内设置禁止输入空格
  2. Unity学习疑问记录之触屏
  3. 最小集合(51nod 1616)
  4. erlang pool模块。
  5. cocos2d-x游戏循环与调度
  6. Mac电脑手动清理
  7. Asp.net Ajax提供PageMethods调用
  8. phpstorm快捷键记录
  9. Centos7-卸载自带的jdk 安装jdk8
  10. Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
  11. python---内置函数,匿名函数,嵌套函数,高阶函数,序列化
  12. 如何修复使用WSUS进行升级Win 10 更新1809的报错(0x8024200)
  13. FREERTOS学习笔记
  14. 关于nexus的学习
  15. Delphi 开发ActiveX控件(非ActiveForm)
  16. NetFPGA Demo ——reference_nic_nf1_cml
  17. linux bash Shell脚本经典 Fork炸弹演示及命令详解
  18. selenium测试(Java)--执行JS(十八)
  19. PetaLinux安装及使用
  20. JS中将字符串中每个单词的首字母大写化

热门文章

  1. 工业物联网网关在线探测之TraceRoute
  2. 图片验证码+session
  3. 从js 讲解时间复杂度和空间复杂度
  4. nginx基本运维及常用配置
  5. DevOps实施历程-v1.0
  6. 关于 java中的换行符
  7. 多态、继承、this、super
  8. curl工具使用实例
  9. 全屏滚动插件pagePiling.js
  10. 如何获取app中的toast