Joseph问题似乎是入门题,就是那个报数出圈的问题,不过它暴力模拟的复杂度是O(nm)的,如果题目的数据范围达到了30000,那就超时了。怎么用线段树维护呢?

我们可以这么考虑,每次我们其实要查询在当前这个点过了m个人是哪一个人。我们需要维护一下当前序列中一共有多少人,还需要维护每个人实际的位置在哪(因为人们出圈了之后他就不占位置了)

我们可以用一棵权值线段树来完成。

首先是修改,这个没什么好说的,直接单点修改改成0就行,然后同时返回修改的位置,这是一个人出圈的位置。不过怎么找到这个位置呢?我们可以首先确定下来这个人在当前序列的第几位,那么我们直接在线段树上二分就可以了,然后返回那个位置。

一开始我们要query一下从1到上一次停留位置有几个人,然后把这个值+m-1,mod现在所有的人数再+1就是当前位置,找一下那个人在哪就可以了。

看一下代码。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<queue>
#include<set>
#define lowbit(x) x & (-x)
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n') using namespace std;
typedef long long ll;
const int M = ;
const ll INF = ; int read()
{
int ans = ,op = ;
char ch = getchar();
while(ch < '' || ch > '')
{
if(ch == '-') op = -;
ch = getchar();
}
while(ch >= '' && ch <= '')
{
ans *= ;
ans += ch - '';
ch = getchar();
}
return ans * op;
} struct seg
{
int v;
} t[M<<]; int n,m,last,g; void build(int p,int l,int r)
{
if(l == r)
{
t[p].v = ;
return;
}
int mid = (l+r) >> ;
build(p<<,l,mid),build(p<<|,mid+,r);
t[p].v = t[p<<].v + t[p<<|].v;
} int query(int p,int l,int r,int pos)
{
if(l == r) return t[p].v = ,l;
int mid = (l+r) >> ,cur;
if(pos <= t[p<<].v) cur = query(p<<,l,mid,pos);
else cur = query(p<<|,mid+,r,pos-t[p<<].v);
t[p].v = t[p<<].v + t[p<<|].v;
return cur;
} int count(int p,int l,int r,int kl,int kr)
{
if(kl > kr) return ;
if(l == kl && r == kr) return t[p].v;
int mid = (l+r) >> ;
if(kr <= mid) return count(p<<,l,mid,kl,kr);
else if(kl > mid) return count(p<<|,mid+,r,kl,kr);
else return count(p<<,l,mid,kl,mid) + count(p<<|,mid+,r,mid+,kr);
} int main()
{
n = read(),m = read();
build(,,n);
rep(i,,n) printf("%d ",last = query(,,n,(count(,,n,,last)+m-)%t[].v+));
return ;
}

Joseph问题 (线段树)的更多相关文章

  1. J - Joseph and Tests Gym - 102020J (二分+线段树)

    题目链接:https://cn.vjudge.net/contest/283920#problem/J 题目大意:首先给你n个门的高度,然后q次询问,每一次询问包括两种操作,第一种操作是将当前的门的高 ...

  2. bzoj3932--可持久化线段树

    题目大意: 最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第 ...

  3. codevs 1082 线段树练习 3(区间维护)

    codevs 1082 线段树练习 3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master 题目描述 Description 给你N个数,有两种操作: 1:给区 ...

  4. codevs 1576 最长上升子序列的线段树优化

    题目:codevs 1576 最长严格上升子序列 链接:http://codevs.cn/problem/1576/ 优化的地方是 1到i-1 中最大的 f[j]值,并且A[j]<A[i] .根 ...

  5. codevs 1080 线段树点修改

    先来介绍一下线段树. 线段树是一个把线段,或者说一个区间储存在二叉树中.如图所示的就是一棵线段树,它维护一个区间的和. 蓝色数字的是线段树的节点在数组中的位置,它表示的区间已经在图上标出,它的值就是这 ...

  6. codevs 1082 线段树区间求和

    codevs 1082 线段树练习3 链接:http://codevs.cn/problem/1082/ sumv是维护求和的线段树,addv是标记这歌节点所在区间还需要加上的值. 我的线段树写法在运 ...

  7. PYOJ 44. 【HNSDFZ2016 #6】可持久化线段树

    #44. [HNSDFZ2016 #6]可持久化线段树 统计 描述 提交 自定义测试 题目描述 现有一序列 AA.您需要写一棵可持久化线段树,以实现如下操作: A v p x:对于版本v的序列,给 A ...

  8. CF719E(线段树+矩阵快速幂)

    题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...

  9. 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序

    3779: 重组病毒 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 224  Solved: 95[Submit][Status][Discuss] ...

随机推荐

  1. 五段实用的js高级技巧

    技巧一之setTimeout. 应用案例:比如你想一个函数循环执行10次,怎么办?以前通常是先setInterval,然后clearInterval,技巧一就是克服这个问题 复制代码 代码如下: (f ...

  2. java 常用集合类型--以及其特性

    1:集合:   (1) Collection(单列集合)        List(有序,可重复)            ArrayList                底层数据结构是数组,查询快,增 ...

  3. json pickle shelve hashlib collections time

    import json # Json模块提供了四个功能:dumps.dump.loads.load dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = js ...

  4. 易维信(EVTrust)支招五大技巧识别钓鱼网站

    网上购物和网上银行凭借其便捷性和通达性,在互联网上日渐流行.在互联网上,你可以随时进行转账汇款或进行交易.据艾瑞咨询发布<2008-2009年中国网上支付行业发展报告>显示:中国互联网支付 ...

  5. 如何用photoshop输出html网页

    如何用photoshop输出html网页 首先得先对PSD文件做切片,有两种方法: ①使用工具栏上的"切片工具", 然后在图象上划出一块一块的区域. ②使用基于参考线的切片,按ct ...

  6. 自动生成 serialVersionUID 的设置

    1 把鼠标放在类名上,会出现小灯泡的形状 点击 Add ‘serialVersionUID’ field... 即可生成 如果鼠标放在类名上没有出现 Add ‘serialVersionUID’ fi ...

  7. 九度oj 题目1057:众数

    题目1057:众数 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:9744 解决:3263 题目描述: 输入20个数,每个数都在1-10之间,求1-10中的众数(众数就是出现次数最多的数, ...

  8. string数据类型操作【四】

    keys *    用于查找所有的key值 exists mykey     #判断该键是否存在,存在返回1,否则返回0. del mykey        删除键(存在就删除返回1,不存在返回为0) ...

  9. PHP_pear的安装和使用

    --------------            安装pear -------------- pear是PHP的扩展和应用程序库,包含了很多有用的类,安装好php5.0后,pear实际上并没有被安装 ...

  10. hdu - 2066 一个人的旅行(基础最短路)

    http://acm.hdu.edu.cn/showproblem.php?pid=2066 把与草儿相连的城市最短距离置为0,然后进行dijkstra,在t个城市里找出距离最近的一个即可. #inc ...