1. 程式人生 > 實用技巧 >POJ2886 Who Gets the Most Candies? 模擬 約瑟夫環 樹狀陣列 + 二分 / 線段樹

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