poj2886 Who Gets the Most Candies?

Posted 王宜鸣

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2886 Who Gets the Most Candies?相关的知识,希望对你有一定的参考价值。

思路:

先打反素数表,即可确定因子最多的那个数。然后模拟踢人的过程确定对应的人名。模拟的过程使用线段树优化加速。

实现:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <string>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int MAXN = 500005;
 8 
 9 int antiprime[] = {1, 2, 4, 6, 12, 24, 36, 48, 60, 120, 180, 240, 360, 720, 840, 1260, 1680, 2520, 5040, 7560, 10080, 15120, 20160, 25200, 27720, 45360, 50400, 55440, 83160, 110880, 166320, 221760, 277200, 332640, 498960, 554400};
10 int fac[] = {1, 2, 3, 4, 6, 8, 9, 10, 12, 16, 18, 20, 24, 30, 32, 36, 40, 48, 60, 64, 72, 80, 84, 90, 96, 100, 108, 120, 128, 144, 160, 168, 180, 192, 200, 216};
11 
12 int tree[MAXN << 2], num[MAXN], n, k;
13 char name[MAXN][11];
14 
15 void build(int num, int l, int r)
16 {
17     if (l == r) { tree[num] = 1; return; }
18     int m = l + r >> 1;
19     build(num << 1, l, m);
20     build(num << 1 | 1, m + 1, r);
21     tree[num] = tree[num << 1] + tree[num << 1 | 1];
22 }
23 
24 int kick(int num, int l, int r, int x) // 在[l, r]范围内踢掉第x个人
25 {
26     if (l == r) { tree[num] = 0; return l; }
27     int m = l + r >> 1, tmp = tree[num << 1], ans = -1;
28     if (tmp >= x) ans = kick(num << 1, l, m, x);
29     else ans = kick(num << 1 | 1, m + 1, r, x - tmp);
30     tree[num] = tree[num << 1] + tree[num << 1 | 1];
31     return ans;
32 }
33 
34 int main()
35 {
36     while (scanf("%d %d", &n, &k) != EOF)
37     {
38         for (int i = 1; i <= n; i++) scanf("%s %d", name + i, num + i);
39         build(1, 1, n);
40         int now = k, out = -1, cnt = n;
41         int tmp = lower_bound(antiprime, antiprime + 36, n) - antiprime;
42         int w = antiprime[tmp] > n ? tmp - 1 : tmp;
43         for (int i = 0; i < antiprime[w]; i++)
44         {
45             out = kick(1, 1, n, now);
46             cnt--;
47             if (!cnt) break;
48             if (num[out] > 0) now = ((now + num[out] - 1) % cnt + cnt) % cnt;
49             else now = ((now + num[out]) % cnt + cnt) % cnt;
50             now = !now ? cnt : now;
51         }
52         printf("%s %d\n", name[out], fac[w]);
53     }
54     return 0;
55 }

 

以上是关于poj2886 Who Gets the Most Candies?的主要内容,如果未能解决你的问题,请参考以下文章

[poj 2886] Who Gets the Most Candies? 线段树

(线段树,反素数)poj2886-Who Gets the Most Candies?

[POJ2886]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?