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 = ;
int v[N],sum[N<<],n,k;
char name[N][];
int rprim[]= {,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,};///反素数
int nprim[]= {,,,,,,,,,,,,,,,,,,,,,,,,,,,
,,,,,,,,};///反素数的约数个数
void build(int l,int r,int rt)
{
sum[rt]=r-l+;///sum储存这个区间有多少的数
if(l<r)
{
int m=(l+r)>>;
build(lson);
build(rson);
}
}
int update(int l,int r,int rt,int k)
{
sum[rt]--;///这个区间减少一个数
if(l==r)
return l;///返回这个减少的数的原始下标
int m=(l+r)>>;
if(k<=sum[rt<<])///要找的第k个数小于等于左半区间的个数
return update(lson,k);///就递归左子树
else
return update(rson,k-sum[rt<<]);///否则就在右子树,且k-左子树的个数
}
int main( )
{
while(scanf("%d%d",&n,&k)!=EOF)
{
memset(name,,sizeof(name));
for(int i= ; i<=n ;i++)
scanf("%s%d",name[i],&v[i]);
build(,n,);
int tn=n,now,p=;
while(rprim[p]<=n)///找出n里最大的反素数
p++;
for(int i= ; i<rprim[p-] ; i++)///反素数前的都出队
{
now=update(,n,,k);///当前出队的序号
tn--;///剩下的人数
if(v[now]>)///向前数
k=(k-+v[now])%tn;///先减去本身这个位置 然后往前v个 再取模
else
k=((k+v[now])%tn+tn)%tn;///直接往后 然后要取模再取模保证正数
if(k==)///如果刚好是tn 取模会变成0
k=tn;
}
now=update(,n,,k);///得到第最大的反素数个出队的人的序号
printf("%s %d\n",name[now],nprim[p-]);
}
return ;
}
不懂反素数的可以点击此链接:反素数
POJ2886Who Gets the Most Candies?(线段树之约瑟夫)的更多相关文章
- POJ 2886 Who Gets the Most Candies?(线段树·约瑟夫环)
题意 n个人顺时针围成一圈玩约瑟夫游戏 每一个人手上有一个数val[i] 開始第k个人出队 若val[k] < 0 下一个出队的为在剩余的人中向右数 -val[k]个人 val[k ...
- POJ 2886.Who Gets the Most Candies? -线段树(单点更新、类约瑟夫问题)
线段树可真有意思呢续集2... 区间成段的替换和增减,以及区间求和等,其中夹杂着一些神奇的操作,数据离散化,简单hash,区间异或,还需要带着脑子来写题. 有的题目对数据的操作并不是直接按照题面意思进 ...
- POJ2886 Who Gets the Most Candies? 线段树 反素数
题意:有一群小朋友围成一个环,编号1,2,3…N.每个人手上握着一个非0的数字,首先第K个人出列,然后看他手上的数字,假设为m,则从下一个开始第m个人出列,一直如此.并设i为小于等于N的最大反素数,问 ...
- POJ 2886 Who Gets the Most Candies? 线段树。。还有方向感
这道题不仅仅是在考察线段树,还他妹的在考察一个人的方向感.... 和线段树有关的那几个函数写了一遍就对了,连改都没改,一直在转圈的问题的出错.... 题意:从第K个同学开始,若K的数字为正 则往右转, ...
- POJ-2886 Who Gets the Most Candies?---线段树+约瑟夫环
题目链接: https://cn.vjudge.net/problem/POJ-2886 题目大意: N个人围成一圈第一个人跳出圈后会告诉你下一个谁跳出来跳出来的人(如果他手上拿的数为正数,从他左边数 ...
- 【POJ2886】Who Gets the Most Candies?-线段树+反素数
Time Limit: 5000MS Memory Limit: 131072K Case Time Limit: 2000MS Description N children are sitting ...
- POJ 2886 Who Gets the Most Candies? 线段树
题目: http://poj.org/problem?id=2886 左右转的果断晕,题目不难,关键是准确的转啊转.因为题目要求输出约数个数最多的数,所以预处理[1,500000]的约数的个数就行了. ...
- 1521. War Games 2(线段树解约瑟夫)
1521 根据区间和 来确定第k个数在哪 #include <iostream> #include<cstdio> #include<cstring> #inclu ...
- lightoj 1179(线段树)
传送门:Josephus Problem 题意:经典约瑟夫问题,有n个人,每次数到第k个人出列,求剩下的最后一人. 分析:用线段树模拟约瑟夫问题,记录区间的减少情况,然后根据每次数到的人在区间排第几位 ...
随机推荐
- 【总结整理】WebGIS学习-thinkGIS(三):关于影像金字塔、瓦片行列号、分辨率resolution
http://www.thinkgis.cn/topic/541a5206da8db186fd0673ba 1.前言 在上一节中我们知道了屏幕上一像素等于实际中多少单位长度(米或经纬度)的换算方法,而 ...
- Ros学习——C++发布器publisher和订阅器subscriber
1.编写发布器 初始化 ROS 系统 在 ROS 网络内广播我们将要在 chatter 话题上发布 std_msgs/String 类型的消息 以每秒 10 次的频率在 chatter 上发布消息 在 ...
- 算法Sedgewick第四版-第1章基础-011一用链表实现bag、queue、stack
1. package algorithms.ADT; /************************************************************************ ...
- GTK编程
一.简介 GTK(GIMP Toolkit)是一套跨多种平台的图形工具包,按LGPL许可协议发布的.虽然最初是为GIMP写的,但早已发展为一个功能强大.设计灵活的通用图形库.特别是被GNOME选中使得 ...
- Effective Objective-C [上]
网上看到的 http://esoftmobile.com/2013/08/10/effective-objective-c/ 本文是针对<Effective Objective-C>一书的 ...
- c++调用python引号的问题
Boost.Python向python里面传递字符串时,引号是个很关键的问题. const char* cstr="hello \\\" world" // hello ...
- window.location和window.location.href和document.location的关系
1,首先来区分window.location和window.location.href. window.location.href是一个字符串. 而window.location是一个对象,包含属性有 ...
- Charles常见问题汇总
Charles是一款很好用的抓包修改工具,但是如果你不是很熟悉这个工具的话,肯定会遇到各种感觉很莫名其妙的状况,这里就来帮你一一解答下面再说说charles的一些其他常用的功能. 选择请求后,右键可以 ...
- Mac下的UI自动化测试 (三)
使用sikuli进行UI自动化测试固然是方便很多,不用一切都使用AppleScript那烦人的语法,只要界面的UI没有变化,结构的变化不会影响到基于sikuli的自动化,但是基于AppleScript ...
- JavaScript面向对象编程入门
来源极客网 function Person() { var _this = {} //创建一个空的对象,接着我们利用这个"空的对象"承载Person的属性和方法 _this.say ...