GYM

来源:互联网 发布:ubuntu关闭iptables 编辑:程序博客网 时间:2024/05/22 15:04

World of Knights
time limit per test
2.0 s
memory limit per test
256 MB
input
standard input
output
standard output

I woke up tied to an iron chair in a wet basement lighted by a single dying candle. The headache was just like after the graduation party in the knight school, and the bitter of the Princess' poison still remained on my lips. A black thug in a leather armor sat at a metal table in front of me. An ugly grimace on his face was to portray a mockery. He was professionally shuffling a deck of cards. That's what happens if you ask too many questions about Dragon.

I instantly recognized my only companion. It was Black Knight — an assassin, known by offering his victims to play cards against him, promising to release in case of a win. Nobody had managed to beat him so far, but I felt luck was on my side that day.

We played «World of Knights» — a card game popular among farmers and swineherds. Each card in the game had two integer characteristics — cost and resource. I had a card with cost 0 and resource 1 in my hand. Not the best one. On the table in front of me there were n cards, the i-th of which had cost ci and resource ri. Every turn I could exchange a card in my hand with a card from the table whose cost was not greater than the resource of the card in the hand. I needed the n-th card. I felt that if I'd got it, I would have won for sure. I decided to get it in a minimal number of turns, ignoring actions of my opponent, especially since I didn't know any other rules of the game.

Input

The first line contains a single integer n (1 ≤ n ≤ 105) — the number of cards on the table.

Each of the next n lines contains two integers separated by a space: ci and ri (0 ≤ ci, ri ≤ 109) — cost and resource of the i-th card on the table.

Output

In the first line output a single integer k — the minimal number of turns to get the n-th card into the hand.

In the second line output k integers separated by spaces — the numbers of cards to exchange with at each turn. The cards are numbered from 1.

If there are several possible answers, output any of them. If it's impossible to get the n-th card in any number of turns, output «No such luck» without quotes.

Examples
input
61 10 22 42 54 55 10
output
32 4 6
input
51 61 72 46 77 0
output
22 5
input
12 0
output
No such luck




题意:有很多张卡,一开始你有1资源,每种卡有两个变量,分别表示他的价值,和资源数。你可以用等价的资源去换那张卡,然后得到更多的资源……很好懂。


解题思路:我用了线段树+二分。主要思路就是先排序,然后贪心的找你现在拥有的资源能换的最多的资源。这里用线段树,然后线段树查询的范围用二分去确定……但是后来想了想……其实单调栈就能做了……


#include <iostream>#include <vector>#include <algorithm>#include <map>using namespace std;const int maxn = 100005;int tree[maxn << 2]; //线段树数组,看你要存什么int A[maxn]; //原数组,下标1~n//更新节点信息,这里是求最值void pushup(int rt){    if (A[tree[rt << 1]] > A[tree[rt << 1 | 1]])        tree[rt] = tree[rt << 1];    else        tree[rt] = tree[rt << 1 | 1];}//建树void build(int l, int r, int rt){ //l,r表示当前区间,rt表示当前区间在线段树数组中的位置    if (l == r)    {                 //若到达叶子结点        tree[rt] = l; //将该位置存原数组的值        return;    }    int m = (l + r) >> 1; //>>1等于/2    //递归建树    build(l, m, rt << 1);    build(m + 1, r, rt << 1 | 1);    pushup(rt); //建完左右子树后,更新当前节点的值}//查询,这里为求最值,LR代表要查询的区间,lr代表当前区间,rt表示当前节点在数组中的实际位置int query(int L, int R, int l, int r, int rt){    if (R < L)        return -1;    if (L <= l && r <= R) //如果当前区间在查询区间内,直接返回当前存的值        return tree[rt];    int m = (l + r) >> 1;    //累加求答案    int ANS = 0;    if (L <= m)    {        int ttt = query(L, R, l, m, rt << 1);        if (A[ANS] < A[ttt])            ANS = ttt;    }    if (R > m)    {        int ttt = query(L, R, m + 1, r, rt << 1 | 1);        if (A[ANS] < A[ttt])            ANS = ttt;    }    return ANS;}struct card{    int c;    int r;    int i;} cards[100005];bool cmp(card a, card b){    if (a.c == b.c)        return a.r < b.r;    return a.c < b.c;}int n;int lowb(int x){    int l = 1;    int r = n;    int m;    while (l <= r)    {        m = (l + r) / 2;        // cout<<m<<endl;        if (cards[m].c <= x)        {            l = m + 1;        }        else        {            r = m - 1;        }    }    return l - 1;}int main(){    scanf("%d", &n);    int nc;    for (int i = 1; i <= n; i++)    {        scanf("%d%d", &cards[i].c, &cards[i].r);        cards[i].i = i;        nc = cards[i].c;    }    if (n == 1)    {        if (cards[1].c > 1)        {            printf("No such luck\n");            return 0;        }    }    sort(cards + 1, cards + n + 1, cmp);    for (int i = 1; i <= n; i++)    {        A[i] = cards[i].r;    }    A[0] = -110000;    build(1, n, 1);    int ttt = lowb(1);    // cout<<ttt<<endl;    vector<int> ans;    int i = query(1, ttt, 1, n, 1);    if (i == -1)    {        printf("No such luck\n");        return 0;    }    //cout<<i<<endl;    ans.push_back(cards[i].i);    bool flag = 1;    while (cards[i].r < nc)    {        int temp = i;        // cout<<cards[i].r<<endl;        ttt = lowb(cards[i].r);        //  cout<<ttt<<endl;        i = query(1, ttt, 1, n, 1);        if (i == temp)        {            flag = 0;            break;        }        ans.push_back(cards[i].i);    }    if (ans.back() == n)        ans.pop_back();    if (flag)    {        ans.push_back(n);        printf("%d\n", ans.size());        for (int i = 0; i < ans.size(); i++)            if (i != ans.size() - 1)                printf("%d ", ans[i]);            else                printf("%d\n", ans[i]);    }    else        printf("No such luck\n");    return 0;}




原创粉丝点击