• POJ 2886 Who Gets the Most Candies?


    POJ_2886

        由于N比较大,如果像模拟约瑟夫环那样用链表模拟的话,每次查找操作的复杂度是O(N)的,时间上是不允许的。但如果我们用线段树来直接求每次轮到谁的话,每次就只需要O(logN)的时间了。

        于是大概思路就是每次都通过线段树查找相应的位置,然后计算一下F(p)的值并更新结果即可。

    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #define MAXD 500010
    int N, M, K, P, tree[4 * MAXD], card[MAXD], isprime[MAXD], prime[MAXD];
    char name[MAXD][15];
    void update(int cur)
    {
    tree[cur] = tree[2 * cur] + tree[2 * cur + 1];
    }
    void build(int cur, int x, int y)
    {
    int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
    if(x == y)
    {
    tree[cur] = 1;
    return ;
    }
    build(ls, x, mid);
    build(rs, mid + 1, y);
    update(cur);
    }
    void init()
    {
    int i;
    for(i = 1; i <= N; i ++)
    scanf("%s%d", name[i], &card[i]);
    build(1, 1, N);
    }
    void reset(int cur, int x, int y, int k)
    {
    int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
    if(x == y)
    {
    tree[cur] = 0;
    return ;
    }
    if(k <= mid)
    reset(ls, x, mid, k);
    else
    reset(rs, mid + 1, y, k);
    update(cur);
    }
    void getf(int turn, int x, int &ans, int &ansx)
    {
    int i, j, res = 1;
    for(i = 0; prime[i] <= turn; i ++)
    if(turn % prime[i] == 0)
    {
    j = 1;
    while(turn % prime[i] == 0)
    turn /= prime[i], ++ j;
    res *= j;
    }
    if(turn != 1)
    res *= 2;
    if(res > ans)
    ans = res, ansx = x;
    }
    int sum(int cur, int x, int y, int t)
    {
    int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
    if(y <= t)
    return tree[cur];
    if(t <= mid)
    return sum(ls, x, mid, t);
    else
    return tree[ls] + sum(rs, mid + 1, y, t);
    }
    int Search(int cur, int x, int y, int k)
    {
    int mid = (x + y) / 2, ls = 2 * cur, rs = 2 * cur + 1;
    if(x == y)
    return x;
    if(k <= tree[ls])
    return Search(ls, x, mid, k);
    else
    return Search(rs, mid + 1, y, k - tree[ls]);
    }
    void change(int &x)
    {
    int i, j, k = card[x], n;
    n = sum(1, 1, N, x);
    if(k < 0)
    {
    k = (-k - 1) % tree[1] + 1;
    if(n < k)
    x = Search(1, 1, N, tree[1] - k + n + 1);
    else
    x = Search(1, 1, N, n - k + 1);
    }
    else
    {
    k = (k - 1) % tree[1] + 1;
    if(tree[1] - n < k)
    x = Search(1, 1, N, k - tree[1] + n);
    else
    x = Search(1, 1, N, n + k);
    }
    }
    void solve()
    {
    int i, j, x = K, ans = 0, ansx;
    for(i = 1; i <= N; i ++)
    {
    reset(1, 1, N, x);
    getf(i, x, ans, ansx);
    if(i != N)
    change(x);
    }
    printf("%s %d\n", name[ansx], ans);
    }
    void prepare()
    {
    int i, j, k;
    memset(isprime, -1, sizeof(isprime));
    k = sqrt(500000 + 0.5), P = 0;
    for(i = 2; i <= k; i ++)
    if(isprime[i])
    {
    prime[P ++] = i;
    for(j = i * i; j <= k; j += i)
    isprime[j] = 0;
    }
    prime[P ++] = 1000003;
    }
    int main()
    {
    prepare();
    while(scanf("%d%d", &N, &K) == 2)
    {
    init();
    solve();
    }
    return 0;
    }


  • 相关阅读:
    Google开源单元測试框架Google Test:VS2012 配置
    ubuntu16.04 uninstall cuda 9.0 completely and install 8.0 instead
    ubuntu 16.04 安装cuda的方法
    ubuntu垃圾文件清理方法
    行人检测资源(下)代码数据
    行人检测资源(上)综述文献
    开源深度学习架构Caffe
    python pip 安装库文件报错:pip install ImportError: No module named _internal
    Canny算子
    vmware中nat模式中使用静态ip后无法上网的问题
  • 原文地址:https://www.cnblogs.com/staginner/p/2433952.html
Copyright © 2020-2023  润新知