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

POJ-2886 Who Gets the Most Candies?---线段树+约瑟夫环

时间:2018-05-12 02:46:04      阅读:200      评论:0      收藏:0      [点我收藏+]

标签:viso   AC   const   gets   color   模板   #define   顺序   查询   

题目链接:

https://cn.vjudge.net/problem/POJ-2886

题目大意:

N个人围成一圈第一个人跳出圈后会告诉你下一个谁跳出来跳出来的人(如果他手上拿的数为正数,从他左边数A个,反之,从他右边数A个) 跳出来的人所得到的糖果数量和他跳出的顺序有关 所得的糖果数为 (假设他是第k个跳出的) 则他得到的糖数为k能被多少个数整除 

解题思路:

首先将因子个数打表:因子个数打表模板

然后先求出1-n中因子个数最大的为x,约瑟夫环进行x次

用线段树求出每次约瑟夫环后的具体下标。因为随性和约瑟夫环的进行,人在一个一个减少,需要求出约瑟夫环中的第i个在原数组中的下标

 1 #include<iostream>
 2 #include<cstdio>
 3 #define MID(l, r) (l + (r - l) / 2)
 4 #define lson(o) (o * 2)
 5 #define rson(o) (o * 2 + 1)
 6 using namespace std;
 7 typedef long long ll;
 8 const int INF = 1e9 +7;
 9 const int maxn = 2e6 + 10;
10 int  h, w, n;
11 struct node
12 {
13     int l, r, sum;
14 }tree[maxn];
15 int ans[maxn];
16 void build(int o, int l, int r)
17 {
18     tree[o].l = l, tree[o].r = r;
19     if(l == r)
20     {
21         tree[o].sum = 1;
22         return;
23     }
24     int m = MID(l, r);
25     int lc = lson(o), rc = rson(o);
26     build(lc, l, m);
27     build(rc, m + 1, r);
28     tree[o].sum = tree[lc].sum + tree[rc].sum;
29 }
30 int id;
31 void query(int o, int a)//查询第a个数下标,同时删除这个数
32 {
33     if(tree[o].l == tree[o].r)
34     {
35         id = tree[o].l;
36         tree[o].sum = 0;
37         return;
38     }
39     int lc = lson(o), rc = rson(o);
40     if(a <= tree[lc].sum)query(lc, a);
41     else query(rc, a - tree[lc].sum);
42     tree[o].sum = tree[lc].sum + tree[rc].sum;
43 }
44 int divisor_num[maxn];
45 void init(int n)
46 {
47     for(int i = 1; i <= n; i++)
48     {
49         divisor_num[i]++;
50         for(int j = i * 2; j <= n; j += i)
51             divisor_num[j]++;
52     }
53 }
54 int solve(int n)
55 {
56     int max = 0, maxid;
57     for(int i = 1; i <= n; i++)
58         if(divisor_num[i] > max)
59     {
60         max = divisor_num[i];
61         maxid = i;
62     }
63     return maxid;
64 }
65 char name[500005][11];
66 int a[maxn];
67 int main()
68 {
69     int n, m;
70     init(500000);
71     while(scanf("%d%d", &n, &m) != EOF)
72     {
73         for(int i = 1; i <= n; i++)
74             scanf("%s%d", name[i], &a[i]);
75         build(1, 1, n);
76         int ansid = solve(n), mod = n;
77         int t = ansid;
78         while(1)
79         {
80             query(1, m);
81             if(--t == 0)break;
82             mod--;
83             if(a[id] > 0)
84             {
85                 m = m - 1 + a[id];
86                 m = ((m - 1) % mod + mod) % mod + 1;
87             }
88             else
89             {
90                 m = m + a[id];
91                 m = ((m - 1) % mod + mod) % mod + 1;
92             }
93         }
94         printf("%s %d\n", name[id], divisor_num[ansid]);
95     }
96     return 0;
97 }

 

POJ-2886 Who Gets the Most Candies?---线段树+约瑟夫环

标签:viso   AC   const   gets   color   模板   #define   顺序   查询   

原文地址:https://www.cnblogs.com/fzl194/p/9027077.html

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