码迷,mamicode.com
首页 > 其他好文 > 详细

poj2886 Who Gets the Most Candies?

时间:2018-02-22 23:08:23      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:prim   tmp   poj   std   --   aik   name   printf   因子   

思路:

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

实现:

 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?

标签:prim   tmp   poj   std   --   aik   name   printf   因子   

原文地址:https://www.cnblogs.com/wangyiming/p/8460362.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!