zoukankan      html  css  js  c++  java
  • POJ2886 Who Gets the Most Candies? 模拟 约瑟夫环 树状数组 + 二分 / 线段树

    有n件女装,每个女装有魅力指数val,初始指定k,从这个女装开始算然后把这件女装扔了,其得到的分数是 j 的因子个数,然后找下一个女装,若当前女装的val是负数,则逆时针找接下来的第k个,否则顺时针找第k个。

    问最终的最大分数是多少。

    因子个数由于n<=5e5 ,可以考虑提前筛好因子个数函数。难点在于如何找到下一个女装。

    一个log的做法就是维护一颗树状数组,在上面二分第k个即可。

    #pragma warning(disable:4996)
    
    #include<iostream>
    #include<algorithm>
    #include<bitset>
    #include<tuple>
    #include<unordered_map>
    #include<fstream>
    #include<iomanip>
    #include<string>
    #include<cmath>
    #include<cstring>
    #include<vector>
    #include<map>
    #include<set>
    #include<list>
    #include<queue>
    #include<stack>
    #include<sstream>
    #include<cstdio>
    #include<ctime>
    #include<cstdlib>
    #define pb push_back
    #define INF 0x3f3f3f3f
    #define inf 0x7FFFFFFF
    #define moD 1000000003
    #define pii pair<int,int>
    #define eps 1e-8
    #define equals(a,b) (fabs(a-b)<eps)
    #define bug puts("bug")
    #define re  register
    #define fi first
    #define se second
    typedef  long long ll;
    typedef unsigned long long ull;
    const ll MOD = 998244353;
    const int maxn = 5e5 + 5;
    const double Inf = 10000.0;
    const double PI = acos(-1.0);
    using namespace std;
    
    ll mul(ll a, ll b, ll m) {
        ll res = 0;
        while (b) {
            if (b & 1) res = (res + a) % m;
            a = (a + a) % m;
            b >>= 1;
        }
        return res % m;
    }
    
    ll quickPower(ll a, ll b, ll m) {
        ll base = a;
        ll ans = 1ll;
        while (b) {
            if (b & 1) ans = mul(ans, base, m);
            base = mul(base, base, m);
            b >>= 1;
        }
        return ans;
    }
    /*
    ll quickPower(ll a, ll b, ll m) {
        ll base = a;
        ll ans = 1ll;
        while (b) {
            if (b & 1) ans = base * ans, ans %= m;
            base *= base, base %= m;
            b >>= 1;
        }
        return ans;
    }
    */
    
    int readint() {
        int x = 0, f = 1; char ch = getchar();
        while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
        while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
        return x * f;
    }
    
    ll readll() {
        ll x = 0, f = 1; char ch = getchar();
        while (ch < '0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
        while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
        return x * f;
    }
    
    void Put(ll x) {
        if (x > 9) Put(x / 10);
        putchar(x % 10 + '0');
    }
    
    int c[maxn];
    int fac[maxn];
    int n;
    char name[maxn][15];
    int val[maxn];
    
    int ask(int x) {
        int  ans = 0;
        for (; x; x -= x & -x) ans += c[x];
        return ans;
    }
    
    void add(int x, int y) {
        for (; x <= n; x += x & -x) c[x] += y;
    }
    
    
    
    void init() {
        for (int i = 1; i <= maxn - 3; i++) for (int j = i; j <= maxn - 3; j += i) fac[j]++;
    }
    
    int bi_search(int k) {
        int l = 1, r = n;
        while (l < r) {
            int mid = l + r >> 1;
            int t = ask(mid);
            if (t < k) l = mid + 1;
            else r = mid;
        }
        return l;
    }
    
    
    int main() {
        int k;
        n = readint(), k = readint();
        init();
        for (int i = 1; i <= n; i++) scanf("%s", name[i]), val[i] = readint(), add(i, 1);
        int pos = k;
        int tot = n;
        int cnt = 0;
        int ans = -1;
        int res = -1;
        while (cnt < n) {
            cnt++;
            if (fac[cnt] > ans) ans = fac[cnt], res = pos;
            add(pos, -1);
            tot--;
            if (!tot) break;
            int tmp = ask(pos);
            int Next;
            if (val[pos] > 0) {
                val[pos] %= tot;
                Next = bi_search((tmp + val[pos] - 1) % tot + 1);
            }
            else {
                val[pos] *= -1;
                val[pos] %= tot;
                Next = bi_search((tmp + (tot - val[pos] + 1) - 1) % tot + 1);
            }
            pos = Next;
        }
        printf("%s %d", name[res], ans);
    }
  • 相关阅读:
    MySQL 初识别语句,数据库、表、行的增删改查
    mysql如何从全备文件中恢复单个库或者单个表
    Shell 同步时间脚本
    app手机端连接tomcat电脑端服务器
    大于号转义符&gt;---小于号转义符&lt;
    轻松实现页面提交中
    重复提交问题(一)
    json
    ExtJs 6.0+快速入门,ext-bootstrap.js文件的分析,各版本API下载(一)
    ExtJS 6 如何引入Dashboard模版
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13413470.html
Copyright © 2011-2022 走看看