POJ 2886 Who Gets the Most Candies? 线段树

题目: http://poj.org/problem?id=2886

左右转的果断晕,题目不难,关键是准确的转啊转。因为题目要求输出约数个数最多的数,所以预处理[1,500000]的约数的个数就行了。还有利用反素数的做法,太专业了,还是暴力预处理吧。。。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <math.h>
 4 
 5 const int MAXN = 500010;
 6 
 7 struct Tree_Node
 8 {
 9     int left, right, sum;
10     Tree_Node(){}
11     Tree_Node(int left, int right, int sum)
12     {
13         this->left = left;
14         this->right = right;
15         this->sum = sum;
16     }
17 }tree[MAXN<<2];
18 
19 void build(int left, int right, int step)
20 {
21     tree[step] = Tree_Node(left, right, right-left+1);
22     if(tree[step].left == tree[step].right)
23         return;
24     int mid = left + (right-left) / 2;
25     build(left, mid, step<<1);
26     build(mid+1, right, step<<1|1);
27 }
28 
29 int query(int num, int step)
30 {
31     tree[step].sum--;
32     if(tree[step].left == tree[step].right)
33     {
34         return tree[step].left;
35     }
36     if(num <= tree[step<<1].sum)
37         return query(num, step<<1);
38     else
39         return query(num - tree[step<<1].sum, step<<1|1);
40 }
41 
42 int div[MAXN];
43 void cnt_divisible()
44 {
45     int x = sqrt(MAXN);
46     for(int i = 1; i <= x; i++)
47     {
48         int y = MAXN / i;
49         for(int j = i+1; j <= y; j++)
50             div[i*j] += 2;
51         div[i*i]++;
52     }
53 }
54 
55 char name[MAXN][11];
56 int val[MAXN];
57 int main()
58 {
59     cnt_divisible();
60     int n, k;
61     while(scanf("%d %d", &n, &k) != EOF)
62     {
63         build(1, n, 1);
64         for(int i = 1; i <= n; i++)
65             scanf("%s %d", name[i], &val[i]);
66         int ans = 0, num = 0, cnt = 0;
67         while(n > 0)
68         {
69             n--;
70             int x = query(k, 1);
71             if(div[++cnt] > ans)
72             {
73                 ans = div[cnt];
74                 num = x;
75             }
76             if(n == 0)
77                 break;
78             if(val[x] > 0)
79                 k = (k + val[x] - 2) % n + 1;
80             else
81                 k = ((k + val[x] - 1) % n + n) % n + 1;
82         }
83         printf("%s %d
", name[num], ans);
84     }
85     return 0;
86 }
View Code
原文地址:https://www.cnblogs.com/wolfred7464/p/3432272.html