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. 源码学习-String类

    最近在扫描CodeDex时报了一个不能使用String.intern()的字符串来做锁对象的告警,对这个问题有疑问查了些资料,顺便学习一下String类的源码. 1.类定义 String 被final ...

  2. IP_MULTICAST_LOOP

    WINDOWS 中 该选项仅控制接收部分.即设置为0 则控制套接字无法接收自身消息.设置为1 则控制套接字使能接收自身消息. LINUX         中 该先项仅控制发送部分.即设置为0 则控制套 ...

  3. 【BZOJ 1003】[ZJOI2006]物流运输(Dijkstra+DP)

    题链 http://www.lydsy.com/JudgeOnline/problem.php?id=1003 Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n ...

  4. python——进制间的转换

    int(string_num, n)  string_num表示某种进制的字符串,n表示string_num是什么进制数 2.8.16 进制转为10进制:使用int()或者eval() 10 进制转为 ...

  5. 嵌入式linux启动信息完全注释

    嵌入式linux启动信息完全注释 from:http://www.embedlinux.cn/ShowPost.asp?ThreadID=377 摘要 我们在这里讨论的是对嵌入式linux系统的启动过 ...

  6. hdu 1027

    #include<stdio.h> #include<algorithm> using namespace std; int a[1100]; int main() {  in ...

  7. bzoj5105 晨跑 数论lcm

    “无体育,不清华”.”每天锻炼一小时,健康工作五十年,幸福生活一辈子”在清华,体育运动绝对是同学们生活中 不可或缺的一部分.为了响应学校的号召,模范好学生王队长决定坚持晨跑.不过由于种种原因,每天都早 ...

  8. Bzoj3060 [Poi2012]Tour de Byteotia

    3060: [Poi2012]Tour de Byteotia Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 251  Solved: 161 Des ...

  9. 【ZJOI2017 Round1练习&BZOJ4774】D3T2 road(斯坦纳树,状压DP)

    题意: 对于边带权的无向图 G = (V, E),请选择一些边, 使得1<=i<=d,i号节点和 n − i + 1 号节点可以通过选中的边连通, 最小化选中的所有边的权值和. d< ...

  10. 类(Class)

    类 · 目的 面向对象的最主要目的是提高程序的重复使用性. · 包括 属性(attribute).方法(method) · 示例 class Bird(object): have_feather = ...