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


    题目链接:

    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
    ", name[id], divisor_num[ansid]);
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    Android Studio中的Java控制台中出现乱码问题?
    博客第二天——头插法建立单链表
    博客志第一天——判断一个整数N是否是完全平方数?
    绝对定位篇
    JavaScript 事件循环
    var与let变量for遍历的问题
    获取url中参数值
    Js不用for,forEach,map等循环实现九九乘法表
    前端常见浏览器兼容性问题
    js常见面试题
  • 原文地址:https://www.cnblogs.com/fzl194/p/9027077.html
Copyright © 2020-2023  润新知