Loading

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);
}

 

posted @ 2020-08-01 10:02  MQFLLY  阅读(129)  评论(0编辑  收藏  举报