题目描述

有编号从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】约瑟夫问题 Treap的更多相关文章

  1. 【codevs1282】约瑟夫问题

    题目描述 有编号从1到N的N个小朋友在玩一种出圈的游戏.开始时N个小朋友围成一圈,编号为I+1的小朋友站在编号为I小朋友左边.编号为1的小朋友站在编号为N的小朋友左边.首先编号为1的小朋友开始报数,接 ...

  2. fhq treap最终模板

    新学习了fhq treap,厉害了 先贴个神犇的版, from memphis /* Treap[Merge,Split] by Memphis */ #include<cstdio> # ...

  3. BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]

    1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 786  Solved: 391[Submit][S ...

  4. BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

    1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1318  Solved: 498[Submit][ ...

  5. 约瑟夫问题(java实现)

    方法一.自定义的链表实现 package com.code.yuesefu; public class YueSeFuList { public static void main(String[] a ...

  6. Java 解决约瑟夫问题

    约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为约瑟夫环.又称“丢手绢问题”.) 有这样一个故事,15个教徒和15个非教徒在深海遇险必须讲 ...

  7. 非旋treap模板

    bzoj3580 非旋转treap 在大神教导下发现split一段区间时先split右边再split左边比较好写 #include <cstdio> #include <cstdli ...

  8. C#实现约瑟夫环问题

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace orde ...

  9. C语言数组实现约瑟夫环问题,以及对其进行时间复杂度分析

    尝试表达 本人试着去表达约瑟夫环问题:一群人围成一个圈,作这样的一个游戏,选定一个人作起点以及数数的方向,这个人先数1,到下一个人数2,直到数到游戏规则约定那个数的人,比如是3,数到3的那个人就离开这 ...

随机推荐

  1. 20145234黄斐《Java程序设计》第十周学习总结

    教材学习内容总结 网络概述 概述 网络编程技术是当前一种主流的编程技术,随着联网趋势的逐步增强以及网络应用程序的大量出现,所以在实际的开发中网络编程技术获得了大量的使用. 计算机网络概述 IP地址: ...

  2. netty之管道处理流程

    1.我们在使用netty的是有都会存在将channelBuffer的数据处理成相应的String或者自定义数据.而这里主要是介绍管道里面存在的上行和下行的数据处理方式 2.通过一张图片来看一下具体管道 ...

  3. #define NULL ((void *)0)引起的风波

    1. 看下宏定义的结构体 typedef struct { ]; //CMEI/IMEI ]; //server ]; //CMEI/IMEI } Options; 2. 定义的NULL #defin ...

  4. DSP5509的GPIO学习-第5篇

    1. 使用CCS V6.1版本,目前已经不局限于仅仅把实验搞清楚了,要深入去探究内部的原理,本章看下GPIO实验 2. 在CCS启动的时候,提示,这个问题是什么,XDAIS是什么?XDAIS (eXp ...

  5. 【廖雪峰老师python教程】——进程与线程

    多进程 操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换到任务2,任务2执行0.01秒,再切换到任务3,执行0.01秒……这样反复执行下去.表面上看,每个任务都是交替执行的,但是,由于CPU ...

  6. 在VMware虚拟机下安装Linux CentOS7

    1.首先下载并安装VMware虚拟机,下载地址:https://www.vmware.com/cn/products/workstation-pro/workstation-pro-evaluatio ...

  7. 基于物品的协同过滤算法(ItemCF)

    最近在学习使用阿里云的推荐引擎时,在使用的过程中用到很多推荐算法,所以就研究了一下,这里主要介绍一种推荐算法—基于物品的协同过滤算法.ItemCF算法不是根据物品内容的属性计算物品之间的相似度,而是通 ...

  8. nginx web服务器的安装使用

    nginx是一个web服务器(高性能web服务器),类似于apache服务器和iis服务器,由于nginx服务器具有轻量级高并发的特点,目前nginx的使用已经超越了apache. nginx介绍:n ...

  9. LeetCode - 412. Fizz Buzz - ( C++ ) - 解题报告 - to_string

    1.题目大意 Write a program that outputs the string representation of numbers from 1 to n. But for multip ...

  10. 查找当前对象中的方法对象的属性叫做_event_name的方法

    setattr( self, '_events', {e._event_name: e for _, e in getmembers(self, lambda x: ismethod(x) and h ...