POJ 2886 Who Gets the Most Candies?(线段树·约瑟夫环)
题意 n个人顺时针围成一圈玩约瑟夫游戏 每一个人手上有一个数val[i] 開始第k个人出队 若val[k] < 0 下一个出队的为在剩余的人中向右数 -val[k]个人 val[k] > 0 时向左数val[k]个 第m出队的人能够得到m的约数个数个糖果 问得到最多糖果的人是谁
约瑟夫环问题 n比較大 直接模拟会超时 通过线段树能够让每次出队在O(logN)时间内完毕 类似上一道插队的题 线段树维护相应区间还有多少个人没出队 那么当我们知道出队的人在剩余人中排第几个也就能够通过线段树知道他在原始环中排第几个了
至于第几个出队的人糖果最多就是求1...n中约数最多的数 能够利用反素数相关知识
对于不论什么正整数x 其约数的个数记做g(x) 比如g(1)=1 g(6)=4 假设某个正整数x满足 对于随意i(0<i<x) 都有g(i)<g(x) 则称x为反素数
我直接用的别人的反素数表
#include <cstdio>
#define lc p<<1, s, mid
#define rc p<<1|1, mid + 1, e
#define mid ((s+e)>>1)
using namespace std;
const int N = 5e5 + 5;
int tot[N * 4], val[N];
//tot维护相应区间还有多少人没出去
char name[N][20]; int ip[] = {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 div[] = {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
};//反素数相应的约数个数 void pushup(int p)
{
tot[p] = tot[p << 1] + tot[p << 1 | 1];
} void build(int p, int s, int e)
{
if(s == e)
{
tot[p] = 1;
return;
}
build(lc);
build(rc);
pushup(p);
} int update(int p, int s, int e, int x)
{
int ret;
if(s == e)
{
tot[p] = 0;
return s;
}
if(x <= tot[p << 1]) ret = update(lc, x);
else ret = update(rc, x - tot[p << 1]);
pushup(p);
return ret;
} int main()
{
int n, k, m, r, ans, pos;
while(scanf("%d%d", &n, &k) != EOF)
{
build(1, 1, n);
for(int i = 1; i <= n; ++i)
scanf("%s%d", name[i], &val[i]); for(int i = 0; ip[i] <= n; ++i)
{
m = ip[i]; //m为小于等于n的第一个反素数
ans = div[i]; //ans相应m的约数个数
} r = n; //还剩r个人
for(int i = 0; i < m; ++i)
{
r--;
pos = update(1, 1, n, k);
//pos为剩余序列中排第k的人在原始队列中的位置
if(!r) break;
if(val[pos] >= 0) //顺时针
k = (k - 1 - 1 + val[pos]) % r + 1;
//第一个-1是把1開始转换为0開始
//第二个是删除第k个后如今位于第k-1个 要前进val[pos]步
//后面的+1是把0開始换回1開始
else //逆时针
k = ((k - 1 + val[pos]) % r + r) % r + 1;
//逆时针删除第k个后如今还位于第k个 要后退-val[pos]步
}
printf("%s %d\n", name[pos], ans);
} return 0;
}
//Last modified : 2015-07-13 19:13
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
(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
POJ 2886 Who Gets the Most Candies?(线段树·约瑟夫环)的更多相关文章
- POJ 2886.Who Gets the Most Candies? -线段树(单点更新、类约瑟夫问题)
线段树可真有意思呢续集2... 区间成段的替换和增减,以及区间求和等,其中夹杂着一些神奇的操作,数据离散化,简单hash,区间异或,还需要带着脑子来写题. 有的题目对数据的操作并不是直接按照题面意思进 ...
- POJ 2886 Who Gets the Most Candies? 线段树。。还有方向感
这道题不仅仅是在考察线段树,还他妹的在考察一个人的方向感.... 和线段树有关的那几个函数写了一遍就对了,连改都没改,一直在转圈的问题的出错.... 题意:从第K个同学开始,若K的数字为正 则往右转, ...
- POJ 2886 Who Gets the Most Candies? 线段树
题目: http://poj.org/problem?id=2886 左右转的果断晕,题目不难,关键是准确的转啊转.因为题目要求输出约数个数最多的数,所以预处理[1,500000]的约数的个数就行了. ...
- poj 2886 "Who Gets The Most Candies?"(树状数组)
传送门 参考资料: [1]:http://www.hankcs.com/program/algorithm/poj-2886-who-gets-the-most-candies.html 题意: 抢糖 ...
- POJ2886Who Gets the Most Candies?(线段树之约瑟夫)
约瑟夫问题的升级版,每次出去的是前一个出去的人位置+手上的数字(正往前,负往后).第i个出去的人拿的糖是i的约数的个数.求拿糖最多的人和他的糖果数. 这里用到了反素数的知识,在这直接打表 题目 AC代 ...
- 线段树(单点更新) POJ 2886 Who Gets the Most Candies?
题目传送门 #include <cstdio> #include <cstring> #define lson l, m, rt << 1 #define rson ...
- POJ 2828 Buy Tickets(排队问题,线段树应用)
POJ 2828 Buy Tickets(排队问题,线段树应用) ACM 题目地址:POJ 2828 Buy Tickets 题意: 排队买票时候插队. 给出一些数对,分别代表某个人的想要插入的位 ...
- POJ 2886 Who Gets the Most Candies? (线段树)
[题目链接] http://poj.org/problem?id=2886 [题目大意] 一些人站成一个圈,每个人手上都有一个数字, 指定从一个人开始淘汰,每次一个人淘汰时,将手心里写着的数字x展示 ...
- poj 2886 Who Gets the Most Candies?(线段树和反素数)
题目:http://poj.org/problem?id=2886 题意:N个孩子顺时针坐成一个圆圈且从1到N编号,每个孩子手中有一张标有非零整数的卡片. 第K个孩子先出圈,如果他手中卡片上的数字A大 ...
随机推荐
- ios—项目开发需求文档
电子商务产品项目需求方案 模块 标准 接入方式 后台(大致需求说明) 前端 购 实物 多商户接入,可支付商品: 基础功能 功能说明 所有须要 Lbs .城市选择,分享.商区.搜索.返回.关闭 LBS: ...
- js---05 自定义属性
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...
- 55.npm install 报错 :stack Error: Can't find Python executable "python"
转自:https://www.cnblogs.com/zengry/p/8044379.html 解决方法 : 1. 安装python , 设置环境变量 :cmd --> path='%path ...
- C/C++(基础-运算符详解)
运算符 任何表达式是有值的 int a = 2; int b = 3; a*=b+4;//a=a*(b+4);"*"*=的优先级层次和=号的层次一样. printf("% ...
- [TypeScript] Restrict null and undefined via Non-Nullable-Types in TypeScript
This lesson introduces the --strictNullChecks compiler option and explains how non-nullable types di ...
- POJ 1442 Black Box treap求区间第k大
题目来源:POJ 1442 Black Box 题意:输入xi 输出前xi个数的第i大的数 思路:试了下自己的treap模版 #include <cstdio> #include < ...
- CSS3:元素的边框、背景和大小
边框 和边框相关的属性例如以下. border-width 用于设置边框的宽度,可选择包含: 1)<长度值>:将边框宽度设为以CSS度量单位(如em.px.cm)表达的长度值. 2)< ...
- C. Arthur and Table(Codeforces Round #311 (Div. 2) 贪心)
C. Arthur and Table time limit per test 1 second memory limit per test 256 megabytes input standard ...
- Multiple CPUs,Multiple Cores、Hyper-Threading
CPU Basics: Multiple CPUs, Cores, and Hyper-Threading Explained 现在多数的家用电脑,仍然使用的是 Single CPU,Multiple ...
- map(froeach改变值,map生成新数组)
http://www.365mini.com/page/jquery-map.htm <input id="n1" name="uid" type=&qu ...