poj 2886 Who Gets the Most Candies?



Who Gets the Most Candies?
Time Limit: 5000MS Memory Limit: 131072K
Total Submissions: 13941 Accepted: 4410
Case Time Limit: 2000MS

Description

N children are sitting in a circle to play a game.

The children are numbered from 1 to N in clockwise order. Each of them has a card with a non-zero integer on it in his/her hand. The game starts from the K-th child, who tells all the others the integer on his card and jumps out of the circle. The integer on his card tells the next child to jump out. Let A denote the integer. If A is positive, the next child will be the A-th child to the left. If A is negative, the next child will be the (A)-th child to the right.

The game lasts until all children have jumped out of the circle. During the game, the p-th child jumping out will get F(p) candies where F(p) is the number of positive integers that perfectly divide p. Who gets the most candies?

Input

There are several test cases in the input. Each test case starts with two integers  N (0 <  N  ≤ 500,000) and K (1 ≤ K ≤ N) on the first line. The next N lines contains the names of the children (consisting of at most 10 letters) and the integers (non-zero with magnitudes within 108) on their cards in increasing order of the children’s numbers, a name and an integer separated by a single space in a line with no leading or trailing spaces.

Output

Output one line for each test case containing the name of the luckiest child and the number of candies he/she gets. If ties occur, always choose the child who jumps out of the circle first.

Sample Input

4 2
Tom 2
Jack 4
Mary -1
Sam 1

Sample Output

Sam 3

Source

提示

题意:

有n个小盆友围成一圈玩游戏。

我们以顺时针方向为每个小盆友标从1-n号(0<n<=500000),游戏规则是给每个人一张卡,卡上写有一个整数。游戏从第k个小盆友开始且这位小盆友出圈,若手上的是正数p,则向右数(顺时针)p个人,若是负数,则向左数(逆时针)p个人。直至全部人出圈,第i个人出圈将会得到 i 的因子个数的糖果数,求出得到最多糖果数小盆友的名字以及他的糖果数量。

思路:

首先我们要知道什么时候糖果数为最多,这时就需要反素数打表了。

反素数:一个区间内存在一个数x,x的因子数大于区间内任何一个数的因子数我们把它称作反素数。

怎么求?直接打表就行了,它又不会随着数据的变化而变化。

之后用线段树去模拟过程找出第x个人就行了。

至于查找的思路去看看这篇blog:http://www.cnblogs.com/CheeseZH/archive/2012/04/29/2476134.html

示例程序

Source Code

Problem: 2886		Code Length: 1604B
Memory: 12344K		Time: 1079MS
Language: GCC		Result: Accepted
#include <stdio.h>
struct
{
    int val;
    char name[11];
}a[500001];
int x[40]={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,500001};
int gx[40]={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,0};
int pos,line[2000000];
void bulid(int t,int l,int r)
{
    int mid;
    line[t-1]=r-l+1;
    if(l==r)
    {
        return;
    }
    mid=(l+r)/2;
    bulid(t*2,l,mid);
    bulid(t*2+1,mid+1,r);
}
void update(int t,int l,int r,int k)
{
    int mid;
    line[t-1]--;
    if(l==r)
    {
        pos=l;
        return;
    }
    mid=(l+r)/2;
    if(line[t*2-1]>=k)
    {
        update(t*2,l,mid,k);
    }
    else
    {
        update(t*2+1,mid+1,r,k-line[t*2-1]);
    }
}
int main()
{
    int n,m,k,i,i1,max;
    while(scanf("%d %d",&n,&k)!=EOF)
    {
        for(i=1;n>=i;i++)
        {
            scanf("%s %d",a[i].name,&a[i].val);
        }
        bulid(1,1,n);
        i=0;
        while(n>=x[i])
        {
            i++;
        }
        max=gx[i-1];
        i=x[i-1];
        m=n;
        while(i!=0)
        {
            m--;
            i--;
            update(1,1,n,k);
            if(m==0)
            {
                break;
            }
            if(a[pos].val>0)			//顺时针
            {
                k=(k+a[pos].val-2)%m+1;
            }
            else				//逆时针
            {
                k=((k+a[pos].val-1+m)%m+m)%m+1;
            }
        }
        printf("%s %d\n",a[pos].name,max);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值