zoukankan      html  css  js  c++  java
  • POJ 2886 Who Gets the Most Candies? (树状数组)

      感觉树状数组要比线段树优雅。。。反素数打表什么的都搞好了,就是从当前位置推下一个位置的公式没搞出来,后来看得别人的。。。

    if(p[now].x > 0)  nxt = (nxt - 1 + p[now].x)%leave;

    else      nxt = ((nxt + p[now].x)%leave + leave)%leave;

    然后在树状数组里找第nxt大的数(二分)。。。

    View Code
    //#pragma comment(linker,"/STACK:327680000,327680000")
    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <vector>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <functional>
    #include <numeric>
    #include <sstream>
    #include <stack>
    #include <map>
    #include <queue>
    
    #define CL(arr, val)    memset(arr, val, sizeof(arr))
    #define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
    #define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
    #define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
    #define L(x)    (x) << 1
    #define R(x)    (x) << 1 | 1
    #define MID(l, r)   (l + r) >> 1
    #define Min(x, y)   (x) < (y) ? (x) : (y)
    #define Max(x, y)   (x) < (y) ? (y) : (x)
    #define E(x)        (1 << (x))
    #define iabs(x)     (x) < 0 ? -(x) : (x)
    #define OUT(x)  printf("%I64d\n", x)
    #define Read()  freopen("data.in", "r", stdin)
    #define Write() freopen("data.out", "w", stdout);
    
    const double eps = 1e-8;
    typedef long long LL;
    const int inf = ~0u>>2;
    
    using namespace std;
    
    const int N = 500010;
    const int M = 1024;
    
    struct node {
        int a, b;
        node() {}
        node(int x, int y) : a(x), b(y) {}
        bool operator < (const node cmp) const {
            return b < cmp.b;
        }
    }f[M];
    
    bool vis[M];
    int prime[M];
    int cnt, num;
    
    void get_prime() {
        int i, j;
        CL(vis, true);
        for(i = 2; i < M; ++i) {
            for(j = i*i; j < M; j += i) {
                vis[j] = false;
            }
        }
        cnt = 0;
        for(i = 2; i < M; ++i) {
            if(vis[i])  prime[cnt++] = i;
        }
    }
    
    void solve(int pnum, int val, int pos, int lim) {
        if(val > N) return ;
    
        f[num++] = node(pnum, val);
        LL nlim, nval, npnum;
        nval = val; nlim = 0; npnum = 1;
        while(nlim < lim && nval <= N) {
            nlim++; npnum++; nval *= prime[pos];
            if(nval <= N)   solve(npnum*pnum, nval, pos + 1, nlim);
        }
    }
    
    void get_antiprime() {
        get_prime();
        num = 0;
        solve(1, 1, 0, 32);
        sort(f, f + num);
    }
    
    //---------上面全是打表------------------
    
    int C[N], n;
    int lowbit(int i)   {return i&(-i);}
    void Add(int p, int val) { while(p <= n) {C[p] += val; p += lowbit(p);} }
    int Sum(int p) {
        int res = 0;
        while(p > 0) {
            res += C[p];
            p -= lowbit(p);
        }
        return res;
    }
    
    struct pnode {
        char name[20];
        int x;
    } p[N];
    
    int bs(int k) {
        int l = 1, r = n, mid, tmp;
        while(r - l >= 1) {
            mid = MID(l, r);
            tmp = Sum(mid);
            if(tmp >= k)    r = mid;
            else    l = mid + 1;
        }
        //printf("%d %d\n", l, r);
        return r;
    }
    
    int main() {
        //Read();
        get_antiprime();
        int k, i, g, mx;
        int now, cnt, nxt, nn, m;
        while(scanf("%d%d", &n, &k) != EOF) {
            CL(C, 0);
            for(i = 1; i <= n; ++i) {
                scanf("%s %d", p[i].name, &p[i].x);
                Add(i, 1);
            }
            mx = 0; g = 0;
            for(i = 0; i < num && f[i].b <= n; ++i) {
                if(f[i].a > mx) {
                    mx = f[i].a; g = f[i].b;
                }
            }
            now = nxt = k; cnt = 1;
            while(cnt < g) {
                nn = n - cnt;
                m = p[now].x;
                if(m > 0)    nxt = (nxt - 1 + m%nn)%nn;
                else   nxt = ((nxt + m)%nn + nn)%nn;
                if(nxt == 0)    nxt = nn;
                Add(now, -1);
                //printf("%d %s\n", now, p[now].name);;
                now = bs(nxt);
                //printf("%d %d %d\n", now, nxt, nn);
                cnt++;
            }
            printf("%s %d\n", p[now].name, mx);
        }
        return 0;
    }
  • 相关阅读:
    网络爬虫之第一章网络请求
    rabbitmq学习(一) —— 安装篇
    jenkins自动构建部署
    httpclient初步封装
    谈谈“拥抱变化”
    mongo对分组数据进行排序
    困兽
    go语言——goland中项目目录及编译说明
    最长回文子串
    java中关于锁知识的整理
  • 原文地址:https://www.cnblogs.com/vongang/p/2743149.html
Copyright © 2011-2022 走看看