POJ (线段树) Who Gets the Most Candies?

这道题综合性挺强的,又牵扯到数论,又有线段树。

线段树维护的信息就是区间中有多少个人没跳出去,然后计算出下一个人是剩下的人中第几个。

我在这调程序调了好久,就是那个模来模去的弄得我头晕。

不过题确实是好题,给赞。

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cmath>
 4 #include <string>
 5 #include <algorithm>
 6 #include <vector>
 7 using namespace std;
 8
 9 const int maxn = 500000 + 10;
10 int n, k;
11 int sum[maxn << 2];
12
13 void build(int o, int L, int R)
14 {
15     if(L == R) { sum[o] = 1; return; }
16     int M = (L + R) / 2;
17     build(o*2, L, M);
18     build(o*2+1, M+1, R);
19     sum[o] = sum[o*2] + sum[o*2+1];
20 }
21
22 int update(int o, int L, int R, int p)
23 {
24     if(L == R) { sum[o] = 0; return L; }
25     int M = (L + R) / 2;
26     int ans;
27     if(sum[o*2] >= p) ans = update(o*2, L, M, p);
28     else ans = update(o*2+1, M+1, R, p-sum[o*2]);
29     sum[o] = sum[o*2] + sum[o*2+1];
30     return ans;
31 }
32
33 const int maxp = 750;
34 int prime[maxp], pcnt = 0;
35 bool vis[maxp];
36
37 void prime_table()
38 {
39     int m = sqrt(maxp);
40     for(int i = 2; i <= m; i++) if(!vis[i])
41         for(int j = i * i; j < maxp; j += i) vis[j] = true;
42     for(int i = 2; i < maxp; i++) if(!vis[i]) prime[pcnt++] = i;
43 }
44
45 int F(int n)
46 {
47     int ans = 1;
48     for(int i = 0; i < pcnt && n > 1; i++) if(n % prime[i] == 0)
49     {
50         int c = 0;
51         while(n % prime[i] == 0) { n /= prime[i]; c++; }
52         ans *= c + 1;
53     }
54     if(n > 1) ans <<= 1;
55     return ans;
56 }
57
58 int next[maxn];
59 char stu[maxn][11];
60
61 int main()
62 {
63     //freopen("in.txt", "r", stdin);
64
65     prime_table();
66
67     while(scanf("%d%d", &n, &k) == 2)
68     {
69         build(1, 0, n - 1);
70         int _max = 0, id;
71         for(int i = 0; i < n; i++) { scanf("%s%d", stu[i], &next[i]); }
72
73         int pos = k - 1;
74         for(int i = 1; i <= n; i++)
75         {
76             int t = update(1, 0, n - 1, pos + 1);
77             int f = F(i);
78             if(f > _max)
79             {
80                 _max = f;
81                 id = t;
82             }
83             if(i == n) break;
84             int MOD = n - i;
85             if(next[t] < 0) next[t]++;  //负数的情况还要有一点小改动,在这坑了好久
86             pos = (((pos + next[t] - 1) % MOD) + MOD) % MOD;
87         }
88         printf("%s %d\n", stu[id], _max);
89     }
90
91     return 0;
92 }

代码君

时间: 2024-10-18 10:07:42

POJ (线段树) Who Gets the Most Candies?的相关文章

Buy Tickets+POJ+线段树单点更新的灵活运用

Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 12927   Accepted: 6410 Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue- The Lunar New Year wa

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

POJ 2886 Who Gets the Most Candies? 反素数+线段树

题意:变形的约瑟夫环模型,每个人有一个数字a,从第K个人开始出列,如果数字是正的,就往后数a个人出列,如果书负数,就往反方向数. 然后用最基本的线段树处理约瑟夫环的方法即可 但是题目要求的是第x个出列的人的名字,x为1-N中约数最多的数中的最小的那个.这里需要求反素数,即不大于N约数最多的. 写起来比较多,容易写错,一开始连素数打表都写作了QAQ #include <cstdio> #include <iostream> #include <cstring> #incl

POJ 题目2513 Who Gets the Most Candies?(线段树)

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

POJ 2886 Who Gets the Most Candies(线段树+约瑟夫环)

题目链接:POJ 2886 Who Gets the Most Candies [题目]N个孩子顺时针坐成一个圆圈,从1~N编号,每个孩子手中有一张标有非零整数的卡片.第K个孩子先出圈,如果他手中卡片上的数字A>0,下一个出圈的是他左手边第A个孩子.A<0,下一个出圈的是他右手边第(-A)个孩子.第p个出圈的孩子会得到F(p)个糖果,F(p)为p的因子数.输出得到糖果数最多的孩子的名字及糖果数目. [思路]孩子数目很大(1~500000),于是想到要用线段树来优化,然后就是模拟出圈过程.并更新

POJ 2886 Who Gets the Most Candies?(线段树模拟约瑟夫环,高合成数)

POJ 2886 Who Gets the Most Candies?(线段树模拟约瑟夫环,高合成数) ACM 题目地址:POJ 2886 Who Gets the Most Candies? 题意: N 个小孩围成一圈,他们被顺时针编号为 1 到 N.每个小孩手中有一个卡片,上面有一个非 0 的数字,游戏从第 K 个小孩开始,他告诉其他小孩他卡片上的数字并离开这个圈,他卡片上的数字 A 表明了下一个离开的小孩,如果 A 是大于 0 的,则下个离开的是左手边第 A 个,如果是小于 0 的, 则是

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?(线段树&#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