【codevs1282】约瑟夫问题
题目描述
有编号从1到N的N个小朋友在玩一种出圈的游戏。开始时N个小朋友围成一圈,编号为I+1的小朋友站在编号为I小朋友左边。编号为1的小朋友站在编号为N的小朋友左边。首先编号为1的小朋友开始报数,接着站在左边的小朋友顺序报数,直到数到某个数字M时就出圈。直到只剩下1个小朋友,则游戏完毕。
现在给定N,M,求N个小朋友的出圈顺序。
唯一的一行包含两个整数N,M。(1<=N,M<=30000)
唯一的一行包含N个整数,每两个整数中间用空格隔开,第I个整数表示第I个出圈的小朋友的编号。
5 3
样例输出
3 1 5 2 4
很好想的一道题,就是求出每次需要出圈的人的排名,然后输出并删除。
然而N为30000怎么办?
网上的题解是线段树,然而线段树不能删除,过于麻烦。
于是想到Treap。
代码有点长,但很好理解。
需要注意rn是上次的排名,但是这次第一个人的排名却应该与rn相同,因为已经减少一个人,对应排名-1。
因此rn初始值为1。
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
int l[30001] , r[30001] , num[30001] , si[30001] , rnd[30001] , tot , root;
void pushup(int k)
{
si[k] = si[l[k]] + si[r[k]] + 1;
}
void zig(int &k)
{
int t = l[k];
l[k] = r[t];
r[t] = k;
si[t] = si[k];
pushup(k);
k = t;
}
void zag(int &k)
{
int t = r[k];
r[k] = l[t];
l[t] = k;
si[t] = si[k];
pushup(k);
k = t;
}
void ins(int &k , int x)
{
if(!k)
{
k = ++tot;
num[k] = x;
si[k] = 1;
rnd[k] = rand();
return;
}
si[k] ++ ;
if(x < num[k])
{
ins(l[k] , x);
if(rnd[l[k]] < rnd[k])
zig(k);
}
else
{
ins(r[k] , x);
if(rnd[r[k]] < rnd[k])
zag(k);
}
}
void del(int &k , int x)
{
if(!k) return;
if(x == num[k])
{
if(l[k] * r[k] == 0)
k = l[k] + r[k];
else if(rnd[l[k]] < rnd[r[k]])
zig(k) , del(k , x);
else
zag(k) , del(k , x);
}
else if(x < num[k])
si[k] -- , del(l[k] , x);
else
si[k] -- , del(r[k] , x);
}
int getrank(int k , int x)
{
if(x == num[k]) return si[l[x]] + 1;
else if(x < num[k]) return getrank(l[k] , x);
else return getrank(r[k] , x) + si[l[x]] + 1;
}
int find(int k , int x)
{
if(x <= si[l[k]]) return find(l[k] , x);
else if(x > si[l[k]] + 1) return find(r[k] , x - si[l[k]] - 1);
else return num[k];
}
int main()
{
int n , m , i , rn = 1 , c;
scanf("%d%d" , &n , &m);
for(i = 1 ; i <= n ; i ++ )
ins(root , i);
for(i = 1 ; i <= n ; i ++ )
{
rn = (rn + m - 2 + si[root]) % si[root] + 1;
c = find(root , rn);
printf("%d " , c);
del(root , c);
}
printf("\n");
return 0;
}
【codevs1282】约瑟夫问题的更多相关文章
- 【codevs1282】约瑟夫问题 Treap
题目描述 有编号从1到N的N个小朋友在玩一种出圈的游戏.开始时N个小朋友围成一圈,编号为I+1的小朋友站在编号为I小朋友左边.编号为1的小朋友站在编号为N的小朋友左边.首先编号为1的小朋友开始报数,接 ...
- 约瑟夫问题(java实现)
方法一.自定义的链表实现 package com.code.yuesefu; public class YueSeFuList { public static void main(String[] a ...
- Java 解决约瑟夫问题
约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为约瑟夫环.又称“丢手绢问题”.) 有这样一个故事,15个教徒和15个非教徒在深海遇险必须讲 ...
- C#实现约瑟夫环问题
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace orde ...
- C语言数组实现约瑟夫环问题,以及对其进行时间复杂度分析
尝试表达 本人试着去表达约瑟夫环问题:一群人围成一个圈,作这样的一个游戏,选定一个人作起点以及数数的方向,这个人先数1,到下一个人数2,直到数到游戏规则约定那个数的人,比如是3,数到3的那个人就离开这 ...
- C语言链表实现约瑟夫环问题
需求表达:略 分析: 实现: #include<stdio.h> #include<stdlib.h> typedef struct node { int payload ; ...
- AC日记——约瑟夫问题 codevs 1282
1282 约瑟夫问题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 查看运行结果 题目描述 Description 有编号从1到N的N个小 ...
- Have Fun with Numbers及循环链表(约瑟夫问题)
1. 循环链表(约瑟夫问题) https://github.com/BodhiXing/Data_Structure 2. Have Fun with Numbers https://pta.pate ...
- javascript中使用循环链表实现约瑟夫环问题
1.问题 传说在公元1 世纪的犹太战争中,犹太历史学家弗拉维奥·约瑟夫斯和他的40 个同胞被罗马士兵包围.犹太士兵决定宁可自杀也不做俘虏,于是商量出了一个自杀方案.他们围成一个圈,从一个人开始,数到第 ...
随机推荐
- ubuntu 14.04 配置 jdk1.8
自己在Ubuntu中安装jdk1.8的步骤,记录以方便以后查询. 将下载好的jdk安装包移到/usr/local目录中(我喜欢将自己安装的软件放在/usr/local目录中),解压缩 sudo tar ...
- fail树
前置技能:AC自动机 假设我们有了一个AC自动机,然后在上面进行字符串匹配. 上面是一个有四个字符串的AC自动机(abcde.aacdf.cdf.cde),虚线是fail指针,实线是转移. 这是上一次 ...
- codevs 2830 蓬莱山辉夜
2830 蓬莱山辉夜 http://codevs.cn/problem/2830/ 题目描述 Description 在幻想乡中,蓬莱山辉夜是月球公主,居住在永远亭上,二次设定说她成天宅在家里玩电脑, ...
- [LeetCode] Number of Boomerangs 回旋镖的数量
Given n points in the plane that are all pairwise distinct, a "boomerang" is a tuple of po ...
- [LeetCode] Subsets 子集合
Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be ...
- underscore 源码解读之 bind 方法的实现
自从进入七月以来,我的 underscore 源码解读系列 更新缓慢,再这样下去,今年更完的目标似乎要落空,赶紧写一篇压压惊. 前文 跟大家简单介绍了下 ES5 中的 bind 方法以及使用场景(没读 ...
- MVC系列——MVC源码学习:打造自己的MVC框架(三:自定义路由规则)
前言:上篇介绍了下自己的MVC框架前两个版本,经过两天的整理,版本三基本已经完成,今天还是发出来供大家参考和学习.虽然微软的Routing功能已经非常强大,完全没有必要再“重复造轮子”了,但博主还是觉 ...
- .NET跨平台之旅:升级至ASP.NET 5 RC1,Linux上访问SQL Server数据库
今天微软正式发布了ASP.NET 5 RC1(详见Announcing ASP.NET 5 Release Candidate 1),.NET跨平台迈出了关键一步. 紧跟这次RC1的发布,我们成功地将 ...
- C++知识回顾(一)
感觉世界都是约定好的,每门语言的第一个程序总是Hello World!但是也有一些书似乎是在追求个性,会用一些其他的,但是是Not Hello World!本人需要再学习一下C++,所以从最基础的开始 ...
- jquery option
转--jquery动态添加option示例 http://www.jb51.net/article/45031.htm //js动态添加option var sel= document.getElem ...