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(二):关于level,比例尺scale,分辨率resolution
1.Level包含了一个resolution参数和一个scale参数 瓦片本身: 我们用arcgis切完图后,打开发布的服务或者打开config.xml配置文件,可以看到所切之图的相关配置.如图所示: ...
- Condition实现等待、通知
使用Condition实现等待/通知: import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.L ...
- WOJ 43 电话邀请
并查集缩点这个trick感觉明明用得很广泛,为什么以前都不知道…… 先把$m$条线路从小到大排个序,这样可以保证之前合并出来的一定是最小的,大的代价不会把小的覆盖掉. 维护两个并查集,一个用来缩点,另 ...
- netty中的PoolChunk
数据结构学的烂,看这个类比较的吃力 PoolChunk主要使用long allocate(int normCapacity) 在buffer pool中分配buffer.这个类有几个重要的概念:pag ...
- 使用paramiko连接EC2主机
在亚马逊云上建的主机没有密码,只有一个PEM文件.所以paramiko需要通过该PEM文件登录云主机进行管理 有两种方式,第一种被我注解了 import paramiko ssh = paramiko ...
- C++笔记--模板
一个string模板 简单的定义 template <class C>//模板形式,C是一个类型名字,不一定是某个类的名字 class String{ struct srep; srep ...
- POJ 3411 Paid Roads (状态压缩+BFS)
题意:有n座城市和m(1<=n,m<=10)条路.现在要从城市1到城市n.有些路是要收费的,从a城市到b城市,如果之前到过c城市,那么只要付P的钱, 如果没有去过就付R的钱.求的是最少要花 ...
- 根据Value对Map中的对象进行排序
背景 SortedMap的实现类TreeMap可以按自然顺序或自定义顺序遍历键(key),有时我们需要根据值(Value)进行排序,本文提供了一种简单实现思路. 实现 Comparator接口 使用V ...
- python:格式化输出整数
import math #default print "PI = %f" % math.pi #width = 10,precise = 3,align = left print ...
- Insus Paging Utility Version 2
Insus.NET对GridView或是DataList分页,都是使用自己的分页组件:http://www.cnblogs.com/insus/archive/2009/03/19/1417102.h ...