• lightoj 1097


    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
    " , ans , query(n , 1));
        }
        return 0;
    }
    
  • 相关阅读:
    第一册:lesson forty five。
    第一册:lesson forty three。
    马化腾2015港大演讲。
    Swing实现文件选择(目录选择)附导出
    SVN强制注释
    Websphere内存溢出的日志
    sql server2008 搭建链接服务器成功后查询时报Cannot obtain the schema rowset "DBSCHEMA_TABLES_INFO" for OLE DB provider "SQLNCLI10" for linked server "XXXXX". 的解决方法
    UML图例
    jSP的3种方式实现radio ,checkBox,select的默认选择值。
    通过js子页面回写父页面,改变父页面控件的值
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/6071545.html
Copyright © 2020-2023  润新知