Pku2886 who gets the most candies?
Question:
There is a row numbered 1 ~ N's Children circled clockwise, and each person had a card numbered a [I] in his hand. The game started from the K children, and he showed his card numbers, if a [I] is greater than 0, a [I] child on the left goes out of the circle. Otherwise, a [I] child on the right goes out of the circle and the game continues, knowing that all the children are out of the ring, the P-th out will get f (p) Candy, f (p) indicates the number of P factors, and ask who gets the most candy.
Analysis: In fact, I first knew how to use the line tree to do it.
The idea is roughly like this: by default, each time is counted starting from the first one left, and the count person goes out of the circle clockwise. Therefore, when a person goes out of the circle, he must calculate the number on his left, and then use the card value a [I] on his hand to determine which person should go out of the circle next;
As for the function f (p), it is to first create a table, calculate the antiprime value, and calculate the number of causes. Then, we only need to find the maximum f (p), (P <= N ), then you can figure out who the P person is.
Counter prime number table: http://hi.baidu.com/speakless/blog/item/1be8d61b63711cd5ac6e751f.html
There are two difficulties in using a line segment tree:
1): Find the number of people on the left of the person who just got out of the circle. In fact, we can calculate the number of people on the left of the person who got out of the circle.CodeIt is clear;
2): How to maintain the line segment tree after the count individual goes out of the circle clockwise? Add a field num to the online segment tree to indicate the remaining number of people in the range, the corresponding range is reduced by one;
# Include <iostream> # include <math. h> # define maxn 500010 using namespace STD; const int antiprime [] = {60,120,180,240,360,720,840,126, 110880,166320, 221760,277 200, 332640,498 960, 554400,665 280}; 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}; struct node {int num ;} P [maxn * 4]; struct name {char nm [11];} na [maxn]; int A [maxn]; int N, Count, DEQ; void bulid (int K, int S, int t) {If (S = T) {P [K]. num = 1; return;} int KL = k <1, Kr = KL + 1, mid = (S + T)> 1; bulid (KL, S, mid); bulid (KR, Mid + 1, t); P [K]. num = P [Kr]. num + P [Kl]. num;} void dequeue (int K, int ln, int Q, int S, int t) // ln indicates the number of digits on the left, Q indicates the number of Q users in the specified range to be deleted. [S, T] indicates the current range {If (S = T) {P [K]. num = 0; Count = ln-1; DEQ = s; return;} int KL = k <1, Kr = KL + 1, mid = (S + T)> 1; if (P [Kl]. num> = q) // if the number of left sons is less than Q, the object to be deleted is on the right son, note that the Q value is equal to the number of people on the left son. // The number of people on the left is calculated similarly. If the object to be deleted is on the left son, then, the number of people on the left of the deleted object must be less than the number of people on the right, because ln indicates the total number of dequeue (KL, Ln-P [Kr]. num, Q, S, mid); else dequeue (KR, LN, Q-P [Kl]. num, Mid + 1, t); P [K]. num = P [Kl]. num + P [Kr]. num;} int main () {While (scanf ("% d", & N, & DEQ) = 2) {for (INT I = 1; I <= N; I ++) scanf ("% S % d", Na [I]. nm, & A [I]); bulid (1, 1, n); int tag = 0; while (antiprime [tag] <= N) // return the largest antiprime subscript tag ++ with an antiprime value less than or equal to n; tag --; int CAS = antiprime [tag]; // The person who exits with ith gets the most sugar; Count = DEQ; while (CAS --) {dequeue (1, P [1]. num, Count, 1, n); If (CAS = 0) // This step cannot be saved, because when the remainder is obtained, P [1]. num may be equal to 0 break; if (a [DEQ]> 0) {COUNT = (count + A [DEQ] + P [1]. num) % P [1]. num; If (COUNT = 0) Count = P [1]. num;} else {COUNT = P [1]. num-count; Count = (count-A [DEQ] + P [1]. num) % P [1]. num; If (COUNT = 0) Count = 1; else count = P [1]. num-count + 1 ;}} printf ("% S % d \ n", Na [DEQ]. nm, factornum [tag]);} return 0 ;}