您的位置:首页 > 其它

POJ 2886 Who Gets the Most Candies?(线段树)

2014-01-08 11:12 477 查看
学会了反素数表。


定义

对于任何正整数x,其约数的个数记做g(x).例如g(1)=1,g(6)=4.如果某个正整数x满足:对于任意i(0<i<x),都有g(i)<g(x),则称x为反素数.

举个例子。

12 24是反素数。约数个数为6和8

在12-24之间的所有数的约数个数只会小于等于6.因为只有完全平方数的约数是奇数个。

然后就是线段树的单点更新。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <set>
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#define maxn 500005
using namespace std;

struct node
{
    char name[15];
    int card;
} save[maxn];
int tre[maxn<<2];
int rec;
const 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};
const int factorNum[] = {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};

void pushup(int num)
{
    tre[num]=tre[num<<1]+tre[num<<1|1];
}
void build(int num,int s,int e)
{
    if(s==e)
    {
        tre[num]=1;
        return;
    }
    int mid=(s+e)>>1;
    build(lson);
    build(rson);
    pushup(num);
}
void update(int num,int s,int e,int val)
{
    if(s==e)
    {
        tre[num]=0;
        rec=s;
        return;
    }
    int mid=(s+e)>>1;
    if(tre[num<<1]>=val)update(lson,val);
    else update(rson,val-tre[num<<1]);
    pushup(num);
}
int query(int num,int s,int e,int l,int r)
{
    if(l<=s && r>=e)
    {
        return tre[num];
    }
    int mid=(s+e)>>1;
    if(r<=mid)return query(lson,l,r);
    else if(l>mid)return query(rson,l,r);
    else return query(lson,l,mid)+query(rson,mid+1,r);
}
int main()
{
    int n,k;
   
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        memset(tre,0,sizeof(tre));
        for(int i=1; i<=n; i++)
            scanf("%s%d",save[i].name,&save[i].card);

        build(1,1,n);
        int l,r,ans;
        int tag=0;
        while(antiprime[tag]<=n)tag++;
        int m=antiprime[--tag];
        int tans;
        while(m--)
        {
            update(1,1,n,k);
            tans=rec;
            int pos=save[tans].card;
            if(tans>1)l=query(1,1,n,1,tans-1);
            else l=0;
            if(tans<n)r=query(1,1,n,tans+1,n);
            else r=0;
            int sum=l+r;
            int tmp=pos;
            if(sum!=0)pos=pos%sum;
            if(pos==0)pos=tmp<0?1:-1;
            if(pos<0)
            {
                if(abs(pos)<=l)
                    k=l+pos+1;
                else
                    k=l+r+(pos+l)+1;
            }
            else
            {
                if(pos<=r)
                    k=l+pos;
                else
                    k=pos-r;
            }
        }
        printf("%s %d\n",save[tans].name,factorNum[tag]);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: