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

Who Gets the Most Candies?

Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u

Submit Status

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 theK-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

先用反素数求出1~n中拥有最多因子的数x,从而得到:在第x人出队时 ,最多的candy数maxn

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<string.h>
 4 #define lson o << 1 , l , mid
 5 #define rson o << 1 | 1 , mid + 1 , r
 6 using namespace std;
 7 //list anti prime
 8 int s[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};
 9 int b[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,1314521};
10 int k , n ;
11 char name[500111][11] ;
12 int val[500111] ;
13 int a[2000100];
14
15 void init (int o , int l , int r )
16 {
17     a[o] = r - l + 1 ;
18     if ( l == r ) {
19         return ;
20     }
21     int mid = ( l + r ) >> 1 ;
22     init ( lson ) ;
23     init ( rson ) ;
24 }
25
26 int insert (int x , int o , int l , int r )
27 {
28     a[o]-- ;
29     if ( l == r ) {
30         return l ;
31     }
32     int mid = ( l + r ) >> 1 ;
33     if ( x <= a[o << 1] ) {
34         insert (x , o << 1 , l , mid ) ;
35     }
36     else {
37         insert ( x - a[o << 1] , o << 1 | 1 , mid + 1 , r ) ;
38     }
39 }
40
41 int main ()
42 {
43   //  freopen ( "a.txt" , "r" , stdin ) ;
44     int i , j , maxn , p , pos ;
45     while (~ scanf ("%d%d" , &n , &k ) ) {
46         i = 0 ;
47         while ( s[i] <= n ) {
48             i++ ;
49         }
50         maxn = b[i - 1] ;
51         p = s[i - 1] ;//p-th leave the team must be the most , and was getting as much Max candy the first team , then
52         //we obtain its number of factor
53         for ( i = 1 ; i <= n ; i++ ) {
54             scanf ( "%s%d" , name[i] , &val[i] ) ;
55         }
56         init (1 , 1 , n ) ;
57         i = n ;
58         while ( p-- ) {//so we can only query p childs
59             n-- ;
60             pos = insert ( k , 1 , 1 , i) ;
61             if ( !n ) {
62                 break ;
63             }
64             if ( val[pos] >= 0 ) {//clockwise
65                 k = ( k - 1 + val[pos] - 1 ) % n + 1 ;//relates to the modular arithmetic , make the code from the begining of ‘0‘ ,
66                 //so start to minus one , as with list Vacancy Segment tree , the obtained ‘k‘ is the new tree i-th location
67             }
68             else {//Anti-clockwise
69                 k = ( ( k - 1 + val[pos] ) % n + n ) % n + 1 ;
70             }
71         }
72         printf ( "%s %d\n" , name[pos] , maxn ) ;
73     }
74     return 0 ;
75 }

反素数的应用

时间: 2024-10-18 15:12:59

Who Gets the Most Candies?(线段树 + 反素数 )的相关文章

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

题目链接点击打开链接 题目大意:给出n个人的姓名和手里的一个号码,n个人排成一圈,号码有正有负,代表着正向还是反向移动k个位置,比赛从第k个人开始,把被选到的人踢出,问按踢出的顺序中因子数最多的是谁? 建立线段树,把n个人被踢的顺序找到,然后求出n个人中因子数最多的(最小的数)是谁,这里要用到反素数,详看链接点击打开链接 #include <cstdio> #include <cstring> #include <algorithm> using namespace s

poj 2886 (线段树+反素数打表) Who Gets the Most Candies?

http://poj.org/problem?id=2886 一群孩子从编号1到n按顺时针的方向围成一个圆,每个孩子手中卡片上有一个数字,首先是编号为k的孩子出去,如果他手上的数字m是正数,那么从他左边(顺时针)开始第m个孩子出去,如果是负的 那么从他的右边(也就是逆时针)开始第m个孩子出去~~~一直到所有的孩子出去,另外,第p个出去的孩子可以得到的糖果数量是p的约数个数,问能得到最多糖果的孩子的名字和得到的糖果数目 关于公约数最多的问题,可以利用到反素数,可以首先先打表反素数和对应的约数个数,

poj 2886 Who Gets the Most Candies?(线段树+约瑟夫环+反素数)

Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 9934   Accepted: 3050 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 o

Poj2886Who Gets the Most Candies?线段树

约瑟夫环用线段数搞,一脸搞不出来的样子.反素数,太神了,先打表,然后就可以 O(1)找到因子数最多的.ps:哎.这题也是看着题解撸的. #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cs

POJ 2886 Who Gets the Most Candies?(线段树&#183;约瑟夫环)

题意  n个人顺时针围成一圈玩约瑟夫游戏  每个人手上有一个数val[i]   开始第k个人出队  若val[k] < 0 下一个出队的为在剩余的人中向右数 -val[k]个人   val[k] > 0 时向左数val[k]个  第m出队的人可以得到m的约数个数个糖果  问得到最多糖果的人是谁 约瑟夫环问题  n比较大 直接模拟会超时   通过线段树可以让每次出队在O(logN)时间内完成  类似上一道插队的题  线段树维护对应区间还有多少个人没出队  那么当我们知道出队的人在剩余人中排第几个

[poj 2886] Who Gets the Most Candies? 线段树

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 oth

poj 2886 Who Gets the Most Candies? 线段树动态求第k大的数

题意: n个小孩站一圈,每个小孩拿一个数字,从第k个孩子开始出局,然后下一个出局的孩子是刚刚出局的孩子之前或之后第v个(刚刚出局的孩子的数字是+v则之后v个,-v则之前v个),这样所有孩子终将出局,第p个出局的孩子得f(p)分,f(p)定义为p的因子个数.求分数最高的孩子. 分析: 设顺时针为正方向,关键是模拟出每次出局的孩子是剩下的孩子中的正方向的第几个,设当前要出局的是第k个,然后要求出第k个小孩的下标(pos)以便下一次计算下一个出局的孩子是第几个,这些步骤可用线段树维护. 代码: //p

POJ2886Who Gets the Most Candies?(线段树之约瑟夫)

约瑟夫问题的升级版,每次出去的是前一个出去的人位置+手上的数字(正往前,负往后).第i个出去的人拿的糖是i的约数的个数.求拿糖最多的人和他的糖果数. 这里用到了反素数的知识,在这直接打表 题目 AC代码: #include<stdio.h> #include<string.h> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int N = 500002; int v[N],sum[N<&

POJ2886 Who Gets the Most Candies? 【线段树】+【单点更新】+【模拟】+【反素数】

Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 9416   Accepted: 2868 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 o