【codevs1282】约瑟夫问题 Treap
题目描述
有编号从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的更多相关文章
- 【codevs1282】约瑟夫问题
题目描述 有编号从1到N的N个小朋友在玩一种出圈的游戏.开始时N个小朋友围成一圈,编号为I+1的小朋友站在编号为I小朋友左边.编号为1的小朋友站在编号为N的小朋友左边.首先编号为1的小朋友开始报数,接 ...
- fhq treap最终模板
新学习了fhq treap,厉害了 先贴个神犇的版, from memphis /* Treap[Merge,Split] by Memphis */ #include<cstdio> # ...
- BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]
1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 786 Solved: 391[Submit][S ...
- BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]
1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1318 Solved: 498[Submit][ ...
- 约瑟夫问题(java实现)
方法一.自定义的链表实现 package com.code.yuesefu; public class YueSeFuList { public static void main(String[] a ...
- Java 解决约瑟夫问题
约瑟夫问题(有时也称为约瑟夫斯置换,是一个出现在计算机科学和数学中的问题.在计算机编程的算法中,类似问题又称为约瑟夫环.又称“丢手绢问题”.) 有这样一个故事,15个教徒和15个非教徒在深海遇险必须讲 ...
- 非旋treap模板
bzoj3580 非旋转treap 在大神教导下发现split一段区间时先split右边再split左边比较好写 #include <cstdio> #include <cstdli ...
- C#实现约瑟夫环问题
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace orde ...
- C语言数组实现约瑟夫环问题,以及对其进行时间复杂度分析
尝试表达 本人试着去表达约瑟夫环问题:一群人围成一个圈,作这样的一个游戏,选定一个人作起点以及数数的方向,这个人先数1,到下一个人数2,直到数到游戏规则约定那个数的人,比如是3,数到3的那个人就离开这 ...
随机推荐
- Android APP架构设计——MVP的使用示例
0. 前言 为了更好地进行移动端架构设计,我们最常用的就是MVC.MVP和MVVM,作为三个最耳熟能详的三大架构,应用可谓非常广泛.对于这三种架构设计以及优缺点已经在Android APP架构设计-- ...
- BZOJ1303_中位数图_KEY
题目传送门 较水,开两个桶即可. 题目可以理解为,将大于B的数看为1,小于B的数看为-1,将以B这个数为中位数的序列左右分为两半,加起来为0. code: #include <cstdio> ...
- eclipse报这个错误org.eclipse.swt.SWTError: No more handles (eclipse 和 TeamViewer 冲突)
错误: org.eclipse.swt.SWTError: No more handles at org.eclipse.swt.SWT.error(SWT.java:4387) a ...
- 文件包含漏洞(RFI)
1文件包含漏洞简介 include require include_once require_once RFI综述 RFI是Remote File Inclusion的英文缩写,直译过来就是远 ...
- APP功能性测试-1
疑难点 根据软件说明()或用户需求()验证App的各个功能实现 根据需求,提炼App的用户使用场景,验证功能 根据测试指标,验证功能 根据被测试功能点的特性采用特定的方法进行测试(场景,边界值,,,) ...
- openjudge-2的100次方阶乘
开始进行的第一天 #include <stdio.h> #include <string.h> int main() { int n; scanf("%d" ...
- Django学习总结-之-URLS反向解析
2018-09-15 09:58:49 在CSDN博客审核效率提高之前, 又要在此处向各位唠叨了~ URL 与 URI URL : 统一资源定位符 相当于绝对路径 URI : 统一资源标志符 相当于 ...
- Java并发基础--volatile关键字
一.java内存模型 1.java内存模型 程序运行过程中的临时数据是存放在主存(物理内存)中,但是现代计算机CPU的运算能力和速度非常的高效,从内存中读取和写入数据的速度跟不上CPU的处理速度,在这 ...
- 【递归入门】组合+判断素数:dfs(递归)
题目描述 已知 n 个整数b1,b2,…,bn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整数相加,可分别得到一系列的和. 例如当 n=4,k=3,4 个整数分别为 3,7,12, ...
- HDU 3262/POJ 3829 Seat taking up is tough(模拟+搜索)(2009 Asia Ningbo Regional)
Description Students often have problems taking up seats. When two students want the same seat, a qu ...