POJ2886--Who Gets the Most Candies?
2013-03-31 18:44
423 查看
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
Sample Output
Sam 3
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
/* 反素数的求法。 搜百度搜了好久都找不到细讲的,最后既然搜到队长的博客O(∩_∩)O哈哈~ 显然素数的因子数为2; 至于非素数,可以分解为质因子之积 i=2^b1*3^b2^5^b3------等等 所以i的因子个数=(b1+1)*(b2+1)*(b3+1)~~~*(bn+1) 反素数的求法:筛选法+DP;素数的约数个数显然是2,对于合数,先求出其 一个质因子,假设是a1,则反复试除a1,求得b1,而在DP过程中已经求得了 N/a1的约数个数,设为g(N/a1),则g(N)=g(N/a1)*(b1+1)/b1 求出反素数后,我们就可以得到n内最大的那个反素数设为k,问题转换为如何求得 谁是第k个跳出来的人。 PS:做此题一定小心别左右不分。。。。 */ #include <iostream> #include <cstdio> using namespace std; #define maxn 500108 bool isp[maxn+1000]; int num[maxn+1000]; int yinshu[maxn+1000]; int maxid[maxn+1000];//用来存最大反素数的id char Name[maxn+1000][12]; int nextt[maxn+1000]; int winnerid; struct ST { int l,r,res; }st[4*maxn]; void init()//筛选素数 { isp[1]=1; for(int i=2;i<720;i++) { if(!isp[i]) { for(int j=i*i;j<=maxn;j+=i) { isp[j]=1; if(!yinshu[j])//这里少个判断,WA了若干次 yinshu[j]=i; } } } } void get()//这一步是求出maxn内,每个数因子数的个数 { num[0]=0; num[1]=1; maxid[1]=1; for(int i=2;i<=maxn;i++) { if(!isp[i])num[i]=2;//如果是个素数,那么他的因子数就是2 else//如果不是个素数,那么 { int s,t,ant=1; s=t=i/yinshu[i];//接下来我们要反复除yinshu[i].求出i的质因子yinshu[i]的指数 while(t==yinshu[i]||(isp[t]&&yinshu[i]==yinshu[t])) { t/=yinshu[i]; ant++; } num[i]=num[s]*(ant+1)/ant; } if(num[i]>num[maxid[i-1]]) { maxid[i]=i; } else maxid[i]=maxid[i-1]; } } void buildtree(int id,int l,int r) { st[id].l=l;st[id].r=r; st[id].res=r-l+1; if(l==r)return; int mid=(l+r)>>1; buildtree(2*id,l,mid); buildtree(2*id+1,mid+1,r); } int update(int id,int l,int r,int p)//要来T第P个人 { st[id].res--; if(st[id].l==st[id].r) { return st[id].l; } if(st[2*id].res>=p) { return update(2*id,l,st[2*id].r,p); } else return update(2*id+1,st[2*id+1].l,r,p-st[2*id].res); } int main() { int n,star,sum,p;//sum用来存此时的真实人数 init();get(); while(scanf("%d%d",&n,&star)==2) { sum=n; buildtree(1,1,n); for(int i=1;i<=n;i++) { scanf("%s%d",Name[i],&nextt[i]); } p=star; //想想如何得到要踢的人是第几个人 for(int i=1;i<=n;i++) { int z=update(1,1,n,p); if(i==maxid ) { winnerid=z; } sum--; if(nextt[z]>0)//要踢左边第几个 { if(sum<=1)p=1; else { p=p-1+(nextt[z]%sum); if(p>sum)p-=sum; if(p<=0)p+=sum; } }//这里感觉上不会出错 else//要踢右边第几个,这里就错啦 { if(sum<=1)p=1; else { p=p+(nextt[z]%sum); if(p<=0)p+=sum; if(p>sum)p-=sum; } } } printf("%s %d\n",Name[winnerid],num[maxid ]); } return 0; }
相关文章推荐
- POJ 2886 Who Gets the MostCandies?(线段树+模拟+求数的约数个数)
- poj 2886 Who Gets the Most Candies? 【线段树单点更新 + 反素数】
- POJ 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies? 线段树
- POJ 2886 Who Gets the Most Candies? (高合成数&用线段树维护约瑟夫环)
- POJ 2886 Who Gets the Most Candies? 线段树。。还有方向感
- POJ 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies? [线段树-单点更新]【数据结构】
- poj 2886 Who Gets the Most Candies?(线段树)
- POJ 2886 Who Gets the Most Candies?
- POJ 2886 - Who Gets the Most Candies?
- [poj 2886] Who Gets the Most Candies? 线段树
- POJ 2886 Who Gets the Most Candies?(线段树单点更新+反素数)
- POJ-2886 Who Gets the Most Candies? 线段树|树状数组
- poj 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies? 线段树。。还有方向感
- poj 2886 Who Gets the Most Candies?
- POJ 2886 Who Gets the Most Candies(线段树模拟约瑟夫环)
- POJ 2886 Who Gets the Most Candies?(线段树+反素数)
- POJ 2886 Who Gets the Most Candies?