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
——written by Lyon
一道借助线段树找出第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
相关文章推荐
- POJ 2886 Who Gets the Most Candies?(线段树)
- poj 2886 Who Gets the Most Candies?(线段树、反素数)
- 线段树(单点更新) POJ 2886 Who Gets the Most Candies?
- poj 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies? (线段树)
- poj 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies? 线段树
- POJ_2886_Who Gets The Most Candies_线段树+反素数
- POJ 2886 Who Gets the Most Candies?(反素数+数学推导+模拟+线段树||树状数组+二分)
- POJ - 2886 Who Gets the Most Candies?(线段树)
- poj 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies?
- POJ-2886 Who Gets the Most Candies?(线段树+模拟)
- poj 2886 Who Gets the Most Candies?
- POJ-2886 Who Gets the Most Candies? 线段树 + 反素数
- poj2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies?(线段树)