首页 > 代码库 > POJ 2886 Who Gets the Most Candies?(线段树模拟约瑟夫环,高合成数)
POJ 2886 Who Gets the Most Candies?(线段树模拟约瑟夫环,高合成数)
POJ 2886 Who Gets the Most Candies?(线段树模拟约瑟夫环,高合成数)
ACM
题目地址:POJ 2886 Who Gets the Most Candies?
题意:
N 个小孩围成一圈,他们被顺时针编号为 1 到 N。每个小孩手中有一个卡片,上面有一个非 0 的数字,游戏从第 K 个小孩开始,他告诉其他小孩他卡片上的数字并离开这个圈,他卡片上的数字 A 表明了下一个离开的小孩,如果 A 是大于 0 的,则下个离开的是左手边第 A 个,如果是小于 0 的, 则是右手边的第 -A 个小孩。游戏将直到所有小孩都离开,在游戏中,第 p 个离开的小孩将得到 F(p) 个糖果,F(p) 是 p 的约数的个数,问谁将得到最多的糖果。输出最幸运的小孩的名字和他可以得到的糖果。
分析:
- 线段树模拟约瑟夫环。第k个小孩根据手牌叫下一个小孩的时候,可以计算出那个是从0开始的第几个,然后就转化为排队问题了。
- 然后就是问谁最多的糖果了,其实就是问前n个数中的高合成数。可以先预处理高合成数,或者直接暴力处理每个数的因子个数。
代码:
/* * Author: illuz <iilluzen[at]gmail.com> * Blog: http://blog.csdn.net/hcbbt * File: 2886.cpp * Create Date: 2014-08-06 14:10:51 * Descripton: segment tree */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define lson(x) ((x) << 1) #define rson(x) ((x) << 1 | 1) typedef long long ll; const int N = 500100; const int ROOT = 1; int n, k; int maxid, maxnum; int tab[N]; char name[N][15]; int card[N]; // below is sement point updated version struct seg { ll w; }; struct segment_tree { seg node[N << 2]; void update(int pos) { node[pos].w = node[lson(pos)].w + node[rson(pos)].w; } void build(int l, int r, int pos) { if (l == r) { node[pos].w = 1; return; } int m = (l + r) >> 1; build(l, m, lson(pos)); build(m + 1, r, rson(pos)); update(pos); } // remove the point that the sum of [0, it] is x, return its id int remove(int l, int r, int pos, ll x) { if (l == r) { node[pos].w = 0; return l; } int m = (l + r) >> 1; int res; if (x <= node[lson(pos)].w) res = remove(l, m, lson(pos), x); else res = remove(m + 1, r, rson(pos), x - node[lson(pos)].w); update(pos); return res; } } sgm; // record the num of division, O(nlogn) void pre() { repf (i, 1, N - 1) { for (int j = i; j < N; j += i) tab[j]++; } } void getmaxnum(int n) { maxid = 1; maxnum = tab[1]; repf (i, 2, n) { if (tab[i] > maxnum) { maxnum = tab[i]; maxid = i; } } } int main() { pre(); while (~scanf("%d%d", &n, &k)) { getmaxnum(n); sgm.build(1, n, ROOT); repf (i, 1, n) { scanf("%s%d", name[i], &card[i]); } int pos, rest = n; repf (i, 1, maxid) { pos = sgm.remove(1, n, ROOT, k); if (--rest == 0) break; if (card[pos] > 0) k = (k - 1 + card[pos] - 1) % rest + 1; else k = ((k - 1 + card[pos]) % rest + rest) % rest + 1; } printf("%s %d\n", name[pos], maxnum); } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。