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大 ...
随机推荐
- js中由undefined说起
typeof()函数 返回的是字符串.有六种可能:"number"."string"."boolean"."object" ...
- 30.IntellJ Idea 导入已存在的Maven项目
转自:https://blog.csdn.net/epdc2/article/details/53767386
- C# 爬虫总结
static void Main(string[] args) { //WebRequest request = WebRequest.Create("http://www.cnblogs. ...
- Kinect 开发 —— 常见手势识别(上)
悬浮按钮 (Hover Button) 悬浮按钮通过将鼠标点击换成悬浮然后等待(hover-and-wait)动作,解决了不小心点击的问题.当光标位于按钮之上时,意味着用户通过将光标悬浮在按钮上一段时 ...
- vue+mui+html5+ plus开发的混合应用底部导航的显示与隐藏
1. 模板相关内容(template) <template> <div> <transition :name="transitionName"> ...
- Input/output subsystem having an integrated advanced programmable interrupt controller for use in a personal computer
A computer system is described having one or more host processors, a host chipset and an input/outpu ...
- new不抛出异常nothrow与new_handler
可以看这里: http://blog.csdn.net/huyiyang2010/article/details/5984987 现在的new是会抛出异常的,bad::alloc 如果不想抛出异常两种 ...
- 如何创建Hiren的BootCD USB磁盘 -- 制作U盘启动盘
如何创建Hiren的BootCD USB磁盘 原文 https://www.wintips.org/how-to-create-hirens-bootcd-usb-disk/ 本文基本是谷歌翻译 H ...
- C#截取指定长度中英文字符串方法 (修改)
public static string GetFirstString(string stringToSub, int length) { Regex regex = new Regex(" ...
- php学习笔记4
PHP数据类型: String(字符串), Integer(整型), Float(浮点型), Boolean(布尔型), Array(数组), Object(对象), NULL(空值). 说明:var ...