POJ 2886 Who Gets the Most Candies?

題目:http://poj.org/problem?id=2886

題意:

有一個n個人圍成圓圈,每次有一個人出圈,下一次出圈的人由本次出圈的人決定。

按照出圈的順序,每個人可以獲得不同的糖果,找出可以獲得最多糖果的人。

 第p個出圈的人可以獲得F(p)個糖果。 

思路:

用線段樹維護剩餘的人數。

約瑟夫環+線段樹+反素數

#include <iostream>
#include <cstdio>

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

using namespace std;
const int maxn = 500005;
int tree[maxn << 2];
struct child{
    char name[20];
    int card;
}cc[maxn];

void PushUp(int rt){
    tree[rt] = tree[rt<<1] + tree[rt<<1|1];
}

void build(int l, int r, int rt){
    tree[rt] = r-l+1;
    if (l == r)
        return;
    int  m = (l + r) >> 1;
    build (lson);
    build (rson);
    PushUp(rt);
}

void update(int p, int l, int r, int rt){
    if (l == r) {
        tree[rt] = 0; return;
    }
    int m = (l + r) >> 1;
    if (m >= p) update(p,lson);
    else update(p, rson);
    PushUp(rt);
}

int query(int k, int l, int r, int rt){
    if (l == r)
        return l;
    int m = (l + r) >> 1;
    if (tree[rt << 1] >= k)
        return query(k, lson);
    else
        return query(k - tree[rt << 1], rson);
}
int hash[maxn];
void init(){//打出反素數表
    for (int i = 1; i <= maxn; i ++){
        hash[i] ++;
        for (int j = 2*i; j <= maxn; j += i)
            hash[j] ++;
    }
}
int main(){
    init();
    int n, k;
    while (scanf ("%d %d", &n, &k) != EOF){
        
        for(int i = 1;i <= n;i++)
            scanf("%s%d",cc[i].name,&cc[i].card);
        
        build (1, n, 1);
        
        int maxtemp = hash[1];
        int kk = 1;
        for(int i = 2;i <= n;i++){
            if(maxtemp<hash[i]){
                maxtemp = hash[i];
                kk = i;
            }
        }
        int pos = k; //k爲人在約瑟夫環中的相對位置,pos爲該人在最初的環中的絕對位置
        for(int i = 1;i < kk;i++) {
            update (pos, 1, n, 1); //刪除當前這個人
            //求出下一個人的在約瑟夫環中的相對位置
            k += cc[pos].card;
            if (cc[pos].card > 0) k--; //注意:當num[pos]>0時,pos後面的人的相對位置都要減1
            k = (k % tree[1] + tree[1]) % tree[1]; //sum[1]爲剩餘人的人數
            if (k == 0) k = tree[1];
            //由相對位置求出絕對位置
            pos = query(k, 1, n, 1);
        }
        printf ("%s %d\n", cc[pos].name,hash[kk]);
    }
    return 0;
}


發佈了229 篇原創文章 · 獲贊 12 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章