Who Gets the Most Candies?
Time Limit : 10000/5000ms (Java/Other) Memory Limit : 262144/131072K (Java/Other)
Total Submission(s) : 65 Accepted Submission(s) : 24
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?
4 2 Tom 2 Jack 4 Mary -1 Sam 1
Sam 3
/#include<cstdio>
#include<cstring>#include<iostream>
#define L(u) (u<<1)
#define R(u) (u<<1|1)
using namespace std;
const int N = 500001;
char name[N][11];
int card[N];
int rfact[37]={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 candy[37]={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,1314521};
struct Node{
int r,l,sum;
};
Node node[N<<2];
void build(int u,int left,int right)
{
node[u].l=left; node[u].r=right;
if(left==right)
{
node[u].sum = 1;
return;
}
int mid = (left+right)>>1;
build(L(u),left,mid);
build(R(u),mid+1,right);
node[u].sum = right-left+1;
}
int query(int u,int num)
{
--node[u].sum;
if(node[u].l==node[u].r)
return node[u].l;
if(num<=node[L(u)].sum)
return query(L(u),num);
return query(R(u),num-node[L(u)].sum);
}
int main(void)
{
int n,k,p,sum;
while(~scanf("%d %d",&n,&k))
{
int i = 0;
while(rfact[i]<=n)//求反素数的最大的
i++;
i -= 1;
p = rfact[i];
sum = candy[i];
build(1,1,n);
for(i=1;i<=n;++i)
scanf("%s %d",name+i,card+i);
k--;
int num;
for(i=1;i<=p;++i)
{
n--;//人数每次减一
num = query(1,k+1);
if(i==p)
break;
if(card[num]>0)
k = (k+card[num]-1)%n;
else
k = ((k+card[num])%n+n)%n;
}
printf("%s %d\n",name[num],sum);
}
return 0;
}