zoukankan      html  css  js  c++  java
  • poj 2886 Who Gets the Most Candies?(线段树和反素数)

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

    题意:N个孩子顺时针坐成一个圆圈且从1到N编号,每个孩子手中有一张标有非零整数的卡片。

    第K个孩子先出圈,如果他手中卡片上的数字A大于零,下一个出圈的是他左手边第A个孩子。

    否则,下一个出圈的是他右手边第(-A)个孩子。第p个出圈的孩子会得到F(p)个糖果,F(p)为p的因子数。求得到糖果数最多的是哪个孩子及得到多少糖果。

    跟上一个 约瑟夫环的题目很像,就是加了一个反素数。

    虽然我还是不太理解,但还是无耻的从别人的结题报告上把反素数表copy了下来。。。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <algorithm>
     6 using namespace std;
     7 const int maxn = 500000 + 10;
     8 int val[maxn];
     9 char name[maxn][20];
    10 
    11 int a[37]= {1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,1260,1680,2520,5040,
    12             7560,10080,15120,20160,25200,27720,45360,50400,
    13             55440,83160,110880,166320,221760,277200,332640,498960,500001
    14            };    //反素数表
    15 int b[37]= {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,
    16             100,108,120,128,144,160,168,180,192,200,1314521
    17            };   //反素数对应的值
    18 struct node
    19 {
    20     int l, r, sum;
    21 }tr[maxn<<2];
    22 
    23 void build(int t, int l, int r)
    24 {
    25     tr[t].l = l;  tr[t].r = r;
    26     tr[t].sum = r - l + 1;
    27     if(l == r)
    28         return;
    29     int mid = (l+r)>>1;
    30     build(2*t, l, mid);
    31     build(2*t+1, mid+1, r);
    32 }
    33 int query(int num, int t)
    34 {
    35     tr[t].sum--;
    36     if(tr[t].l == tr[t].r)
    37     return tr[t].l;
    38     if(tr[2*t].sum >= num)
    39     return query(num, 2*t);
    40     else
    41     return query(num-tr[2*t].sum, 2*t+1);
    42 }
    43 int main()
    44 {
    45     int n, k, i, p, Max;
    46     int x;
    47     while(~scanf("%d%d", &n, &k))
    48     {
    49         i = 0;
    50         Max = 0; p = 0;
    51         while(a[i] <= n)
    52         i++;
    53         p = a[i-1]; Max = b[i-1];  //第几个出去的。最大值
    54         build(1, 1, n);
    55         for(i = 1; i <= n; i++)
    56         scanf("%s%d",name[i], &val[i]);
    57 
    58         for(i = 0; i < p; i++)
    59         {
    60             n--;
    61             x = query(k, 1);
    62             if(n == 0)  break;
    63             if(val[x] > 0)
    64             k = (k-1+val[x]-1)%n + 1;
    65             else
    66             k = (k-1+val[x]%n+n)%n + 1;
    67         }
    68         printf("%s %d
    ",name[x], Max);
    69     }
    70     return 0;
    71 }
  • 相关阅读:
    算法-排序(二)-快速排序
    算法- 排序(一)
    python(十四)新式类和旧式类
    Python(十三)python的函数重载
    django(二)中间件与面向切面编程
    MySQL(二)MySQL的启动或链接失败
    django(一)验证码
    python(七) Python中单下划线和双下划线
    Python(十) Python 中的 *args 和 **kwargs
    python(六)列表推导式、字典推导式、集合推导式
  • 原文地址:https://www.cnblogs.com/bfshm/p/3561837.html
Copyright © 2011-2022 走看看