您的位置:首页 > 其它

poj 2886 Who Gets the Most Candies?

2012-10-06 15:56 471 查看
http://poj.org/problem?id=2886

  一道借助线段树找出第k个位置的题。

  题意是,有n个人,他们手中拿着一张写着不为零的数的牌。开始的时候是从第k个人开始的,数到的人出列,然后从那个人的位置开始数d个人,d是他手上的牌的数字,数到的下一个出列,如此反复。第i个出列的人可以得到F(i)个糖果,F(i)是因数的个数。

  这题主要问题在计算下一个人的位置时,如果next(也就是这个人手上拿的数)是负数的话,就要调整一下位置,因为这时的-1相当于是0了。然后质因数,就直接预处理一下,其他的都没什么大问题了。没调整负数的情况,wa了一次。。。

代码如下:

View Code

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>

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

using namespace std;

const int maxn = 500005;
int cntFac[maxn], maxCnt[maxn];

void pre() {
for (int d = 1; d < maxn; d++) {
for (int i = d; i < maxn; i += d) {
cntFac[i]++;
}
}
for (int i = 1; i < maxn; i++) {
maxCnt[i] = (cntFac[maxCnt[i - 1]] >= cntFac[i]) ? maxCnt[i - 1] : i;
}
//    for (int i = 0; i < 20; i++) {
//        printf("%d : %d %d\n", i, cntFac[i], maxCnt[i]);
//    }
}

int rec[maxn], cnt[maxn << 2];
char name[maxn][12];

void up(int rt) {
cnt[rt] = cnt[rt << 1] + cnt[rt << 1 | 1];
}

void build(int l, int r, int rt) {
if (l == r) {
cnt[rt] = 1;
return ;
}
int m = (l + r) >> 1;

build(lson);
build(rson);
up(rt);
}

int locate(int _p, int l, int r, int rt) { // the k-th person, begin from 1
if (l == r) {
cnt[rt] = 0;
return l;
}
int m = (l + r) >> 1, ret;

if (_p <= cnt[rt << 1]) ret = locate(_p, lson);
else ret = locate(_p - cnt[rt << 1], rson);
up(rt);

return ret;
}

int calNext(int cur, int next, int size) {
if (next < 0) next++;
return (((cur + next - 1) % size) + size - 1) % size + 1;
}

int deal(int n, int k) {
int ret = 0, tmp = 0;

build(1, n, 1);
rec[0] = k + 1;
//    printf("%d\n", maxCnt
);
for (int i = 0, endi = maxCnt
; i < endi; i++) {
ret = calNext(ret, rec[tmp], n - i);
tmp = locate(ret, 1, n, 1);
//        printf("ret %d\n", ret);
//        printf("tmp %d\n", tmp);
//        puts("~~~");
}

return tmp;
}

int main() {
int n, k;

//    freopen("in", "r", stdin);
pre();
while (~scanf("%d%d", &n, &k)) {
for (int i = 1; i <= n; i++) {
scanf("%s %d", name[i], &rec[i]);
}
printf("%s %d\n", name[deal(n, k)], cntFac[maxCnt
]);
}

return 0;
}


——written by Lyon
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: