Segment tree title set

Who Gets the Most Candies?

 POJ - 2886 

Emirp segment tree +

Meaning of the questions: There are n people in a circle, the starting point of the game is to k, each person holds a digital num (non-numbered), each time the current circle of people quit, the next person is left of his first num (that is, said a next exit is k + num, k can be negative, represents the right of first num), now if a person has is the i-th launch, so his score is the number factor i, the highest score of the ball of that person's number

Solution: First find which n is equal to less than all of the numbers inside the circle id should get the highest score, the establishment of tree line in accordance with the number of intervals, followed by a ring

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<stack>
#include<cstdlib>
#include<queue>
#include<set>
#include<string.h>
#include<vector>
#include<deque>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f3f3f3f3f
#define inf 0x3f3f3f3f
#define eps 1e-4
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl;

#define Mod(a,b) a<b?a:a%b+b
typedef long long LL;
typedef long long ll;
const int maxn = 5e5 + 5;

int p[16] = {2,3,5,7,11,13,17,19,23,29,31,37,41,43, 47 , 53 is }; 

int ANS, n-;
 int Best; 

void DFS ( int Dept, int tmp, int NUM) {
     // the leaf node, return 
    IF (Dept> = 16 ) return ;
     // NUM recorded factor number, if they are smaller, updated 
    IF (NUM> Best) { 
        Best = NUM; 
        ANS = tmp; 
    } 
    // if the number is the same factor, the smallest value 
    IF (NUM == Best && ANS> tmp) ANS = tmp;
     for ( int i = 1; i <= 63; i++) {
        if (n / p[dept] < tmp) break;
        dfs(dept + 1, tmp *= p[dept], num * (i + 1));
    }
}

int a[maxn],num[maxn],st[maxn << 2];
char name[maxn][20];
void build(int o, int l, int r) {
    if(l == r) st[o] = a[l];
    else {
        int mid = (l + r) >> 1;
        build(o << 1, l, mid);
        build(o << 1 | 1, mid + 1, r);
        st[o] = st[o << 1] + st[o << 1 | 1];
    }
}



int query(int pos,int o,int l,int r) {
    st[o]--;
    if(l == r) return l;
    int mid = (l + r) >> 1;
    int ans;
    if (st[o << 1] >= pos) ans = query(pos,o << 1, l, mid);
    else {
        pos -= st[o << 1];
        ans = query(pos, o << 1 | 1, mid + 1, r);
    }
    return ans;
}
int solve(int x) {
    int tmp = (int)sqrt(x * 1.0),ans = 0;
    for(int i = 1; i <= tmp; i++) {
        if (x % i == 0 && i != x / i) {
            ans += 2;
        } else if(x % i == 0)
            ans += 1;
    }
    return ans;
}
int main() {
    int k;
    while (~scanf("%d %d", &n, &k)) {
        ans = INF;
        best = 0;
        dfs(0, 1, 1);
        for (int i = 1; i <= n; i++) {
            scanf("%s %d",name[i], &num[i]);
            a[i] = 1;
        }
        build(1, 1, n);
        int ret;
        for (int i = 1; i <= ans; i++) {
            int pos = k;
            ret = query(pos, 1, 1, n);
            pos = num[ret];

            if(st[1] == 0) break;
            if(pos > 0) pos = ((k - 2 + st[1]) % st[1] + pos) % st[1] + 1;
            else pos = ((k + pos - 1) % st[1] + st[1]) % st[1] + 1;
            k = pos;
        }
        printf("%s %d\n",name[ret],solve(ans));

    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/smallhester/p/11469521.html