LightOJ 1097 - Lucky Number 线段树

http://www.lightoj.com/volume_showproblem.php?problem=1097

题意:一个自然数序列,先去掉所有偶数项,在此基础上的序列的第二项为3,则删去所有3的倍数的元素,再是7……重复操作,最后问第n项的值

思路:使用线段树构造序列,对一个数进行标记是否已被删去,和为元素个数。由于样例给出了大小,所以很容易控制空间。

/** @Date    : 2016-12-05-19.34
  * @Author  : Lweleth ([email protected])
  * @Link    : https://github.com/
  * @Version :
  */

#include<bits/stdc++.h>
#define LL long long
#define PII pair
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 1429431;
const double eps = 1e-8;

struct yuu
{
    int l, r;
    int sum;
}tt[N * 3];

int ans[100010];

void pushup(int p)
{
    tt[p].sum = tt[p << 1].sum + tt[p << 1 | 1].sum;
}

void build(int l, int r, int p)
{
    tt[p].l = l;
    tt[p].r = r;
    if(l == r)
    {
        tt[p].sum = l & 1;
        return ;
    }
    int mid = (l + r) >> 1;
    build(l , mid, p << 1);
    build(mid + 1, r, p << 1 | 1);
    pushup(p);

}

void updata(int x, int p)
{
    if(tt[p].l == tt[p].r)
    {
        tt[p].sum = 0;
        return ;
    }
    if(x <= tt[p << 1].sum)
        updata(x, p << 1);
    else
        updata(x - tt[p << 1].sum, p << 1 | 1);
    pushup(p);
}

int query(int len, int p)
{
    if(tt[p].l == tt[p].r)
        return tt[p].l;

    if(len <= tt[p << 1].sum)
        query(len, p << 1);
    else query(len - tt[p << 1].sum, p << 1 | 1);

}
int main()
{
    int c = 1;
    ans[1] = 1;
    build(1, 1429431, 1);
    for(int i = 2; i <= 1429431; i++)
    {
        int p = query(i, 1);
        for(int j = 0; p + j <= 1429431; j+=p-1)
            updata(p+j, 1);
        if(c >= 100000)
            break;
        ans[++c] = query(i, 1);
    }
    int T;
    int cnt = 0;
    cin >> T;
    while(T--)
    {
        int n;
        cin >> n;
        printf("Case %d: %d\n", ++cnt, query(n, 1));
    }
    return 0;
}
时间: 2024-08-24 18:41:22

LightOJ 1097 - Lucky Number 线段树的相关文章

Hdu1394Minimum Inversion Number线段树

这个网上一搜一大堆,就是先求一个,其余的for一遍搞出来. #include<stdio.h> #include<stdlib.h> #define max 5555 int sum[max * 4]; int min(int a, int b) { if (a>b) return b; else return a; } void fuqin(int a) { sum[a] = sum[a * 2] + sum[a * 2 + 1]; } void build(int l,

Minimum Inversion Number(线段树单点更新+逆序数)

Minimum Inversion Number(线段树单点更新+逆序数) Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy

hdu 1394 Minimum Inversion Number 线段树 点更新

// hdu 1394 Minimum Inversion Number 线段树 点更新 // // 典型线段树的单点更新 // // 对于求逆序数,刚开始还真的是很年轻啊,裸的按照冒泡排序 // 求出最初始的逆序数,然后按照公式递推,结果就呵呵了 // // 发现大牛都是用线段树和树状数组之类的做的,而自己又在学 // 线段树,所以就敲了线段树. // // 线段树的节点保存一段区间( L,R )内0,1...n一共出现了多少个. // 因为每个数是0,1,2...n-1且没有重复的数字. /

HDU1394_Minimum Inversion Number(线段树/逆序数)

解题报告 题目传送门 题意: 给n个数,每次左移一位,求最小逆序数. 思路: 如果每次左移一位求一次逆序数肯定不行的. 可以知道,每次左移一位,也就是第一个数移到最后一位,逆序数应该减去第一个数以后比第一个数小的个数,再加上比第一个数大的个数. 原本用线段树求出每一位后面比这一位小的个数再用上面的办法求最小逆序数,没有想到每一次移动会导致后面比它本身大的数都要加1. 这题巧妙就在这n个数都在0-n里面,且没有重复. 所以第一个数以后比第一个数小的个数就是第一个数的数值.比它大就是n-1-第一个数

HDU 1394 Minimum Inversion Number.(线段树)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 ~~~~ 早起一发线段树,开心又快乐.这题暴力也能水过,同时线段树的效率也就体现的尤为明显了,看了大牛的博客,说是还可以用树状数组,点树和合并序列写,现在还不懂,留着以后在写吧. ~~~~ 大致题意:给定一个数字序列,同时由此可以得到n个序列, 要求从n个序列中找到逆序数最小的序列,输出最小逆序数. 首先介绍下逆序数的概念: 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面

HDU1394 Minimum Inversion Number 线段树+数学

Problem Description The inversion number of a given number sequence a1, a2, -, an is the number of pairs (ai, aj) that satisfy i < j and ai > aj. For a given sequence of numbers a1, a2, -, an, if we move the first m >= 0 numbers to the end of the

K-th Number 线段树(归并树)+二分查找

K-th Number 题意:给定一个包含n个不同数的数列a1, a2, ..., an 和m个三元组表示的查询.对于每个查询(i, j, k), 输出ai, ai+1, ... ,aj的升序排列中第k个数 . 题解:用线段树,每个节点维护一个区间并且保证内部升序,对于每次查询x,返回该区间小于x的数的个数.就这样不断二分,直到找到x为止. 线段树(归并树)+二分查找 1 #include <iostream> 2 #include <cstdio> 3 #include <

ZOJ 3886 Nico number(线段树)

Nico Number Time Limit: 2 Seconds      Memory Limit: 262144 KB Kousaka Honoka and Minami Kotori are playing a game about a secret of Yazawa Nico. When the game starts, Kousaka Honoka will give Minami Kotori an array A of N non-negative integers. Ther

HDU 1394- Minimum Inversion Number(线段树求逆序数)

Minimum Inversion Number Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1394 Appoint description:  System Crawler  (2015-04-13) Description The inversion number of a given number sequence a1, a