poj2886 Who Gets the Most Candies?反素数+线段树

来源:互联网 发布:随身淘宝皇家小地主3q 编辑:程序博客网 时间:2024/05/21 09:24

分析:约瑟夫环的升级版,求最大糖果数(因子数可用反素数打表获得)

维护一颗线段树,区间存储剩余孩子数

这里涉及一个新的概念: 反素数


#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 500000 + 10;int antiprime[]={1,2,4,6,12,24,36,48,60,120,180,240,360,720,840,                       1260,1680,2520,5040,7560,10080,15120,20160,25200,                       27720,45360,50400,55440,83160,110880,166320,221760,                       277200,332640,498960,554400,665280                };int factor[]={1,2,3,4,6,8,9,10,12,16,18,20,24,30,32,36,40,48,60,                       64,72,80,84,90,96,100,108,120,128,144,160,168,180,                       192,200,216,224             };int seg[maxn<<2];int name[maxn][11], value[maxn];void build(int root, int l, int r){    seg[root] = r-l+1; //初始化    if (l == r) return;    int m = (l+r) >> 1;    build(root<<1, l, m);    build(root<<1|1, m+1, r);}int update(int root, int l, int r, int key){    seg[root] --;    if (l == r) return l;    int m = (l+r) >> 1;    if (seg[root<<1] >= key) update(root<<1, l, m, key);    else update(root<<1|1, m+1, r, key-seg[root<<1]); //类似排队问题}int main(){    int n, k, &mod = seg[1];    while (scanf("%d %d", &n, &k) != EOF){        build(1, 1, n);        for (int i = 1; i<=n; i++){            scanf("%s%d", name[i], &value[i]);        }        int cnt = 0;        while (antiprime[cnt] <= n && cnt < 35) cnt++;        int Max = factor[cnt-1]; //根据反素数打表可求得最大因字数,可推得p值        int p = antiprime[cnt-1];        value[0] = 0;        int pos = 0;        for (int i = 0; i<p; i++){            if (value[pos] > 0){ // 顺时针                k=((k+value[pos]-2)%mod+mod)%mod+1;<span class="comment">//涉及模运算令代号从0开始,所以开始要减1,如同数空位线段树一样,k得到的是新树的第几个位置</span><span>  </span>            }            else{//逆时针                k = ((k+value[pos]-1)%mod+mod)%mod+1;            }            pos = update(1, 1, n, k);        }        printf("%s %d\n", name[pos], factor[cnt-1]);    }    return 0;}


0 0
原创粉丝点击