wikioi 1282 约瑟夫问题 线段树

和上一题一样,寻找第K个位置,只不过需要处理一下下一个位置在哪,画图看看就知道了。

#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 30000+5;
int sum[maxn<<2],a[maxn];
void pushup(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt)
{
    if (l==r) {sum[rt]=1;return;}
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    pushup(rt);
}
int update(int l,int r,int rt,int cnt)
{
    int ret,m=(l+r)>>1;
    if(l==r)
    {
        sum[rt]=0;
        return l;
    }
    if(cnt<=sum[rt<<1]) ret=update(lson,cnt);
    else ret=update(rson,cnt-sum[rt<<1]);
    pushup(rt);
    return ret;
}
int main()
{
    int x,st=1,n,m;
    scanf("%d%d",&n,&m);
    build(1,n,1);
    for(int i=1,last=n;i<=n;i++,last--)
    {
        x=(st+m-1)%last;
        if(x==0) x=last;
        st=x;
        a[i]=update(1,n,1,x);
    }
    for(int i=1;i<=n;i++)
    {
        if(i==1) printf("%d",a[i]);
        else printf(" %d",a[i]);
    }
    puts("");
    return 0;
}

wikioi 1282 约瑟夫问题 线段树

时间: 2024-10-13 11:36:28

wikioi 1282 约瑟夫问题 线段树的相关文章

poj 2886 Who Gets the Most Candies?(线段树+约瑟夫环+反素数)

Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 9934   Accepted: 3050 Case Time Limit: 2000MS Description N children are sitting in a circle to play a game. The children are numbered from 1 to N in clockwise o

POJ 2886 Who Gets the Most Candies?(线段树&#183;约瑟夫环)

题意  n个人顺时针围成一圈玩约瑟夫游戏  每个人手上有一个数val[i]   开始第k个人出队  若val[k] < 0 下一个出队的为在剩余的人中向右数 -val[k]个人   val[k] > 0 时向左数val[k]个  第m出队的人可以得到m的约数个数个糖果  问得到最多糖果的人是谁 约瑟夫环问题  n比较大 直接模拟会超时   通过线段树可以让每次出队在O(logN)时间内完成  类似上一道插队的题  线段树维护对应区间还有多少个人没出队  那么当我们知道出队的人在剩余人中排第几个

Wikioi 1081 线段树练习2

线段树练习飘逸的写法,自从自己改成这种写法之后,线段树就没再练过,现在终于练得上了. 因为这里查询只是查询了叶子结点,所以pushUp函数就用不上了,不过我没去掉之前是3ms,去掉之后反而变成4ms了,搞不懂怎么原因,没用到,去掉之后应该更快才对啊,竟然变慢了,真搞不明白? #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <dequ

Wikioi 1082线段树成段更新成段查询

这题从昨晚搞到现在敲了又改好久,刚开始是update中错了,然后找到了.但是还错,然后因为题目没有数据的范围提示,所以弄了好久都不知道哪错了,最后看评论才知道是超int了,改了之后还有错,然后才发现虽然改成long long了,但是输出的时候没改,哈哈-- #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <deque> #in

wikioi 1080 线段树练习 树状数组

1080 线段树练习 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 一行N个方格,开始每个格子里都有一个整数.现在动态地提出一些问题和修改:提问的形式是求某一个特定的子区间[a,b]中所有元素的和:修改的规则是指定某一个格子x,加上或者减去一个特定的值A.现在要求你能对每个提问作出正确的回答.1≤N<100000,,提问和修改的总数m<10000条. 输入描述 Input Description 输入文件第一行为一个整

约瑟夫环小结(线段树)

题目大意: 输入初始人数编号为1~n,以及初始密码m,输出出局序列. 解法一:用线段树可解. Segtree节点存储左右区间和该区间下包含的人数. void Build(int p,int left,int right)表示从编号为p,区间为[l,r]的节点开始向下建树. int Update(int p,int id)表示从编号为p的节点开始查询在新队伍中编号为id的人出局,返回该人在最初队伍中的编号. 而temp=(temp+m-1)%seg[1].manum;语句用于求出下一个出局的人在新

POJ 2886 Who Gets the Most Candies(线段树+约瑟夫环)

题目链接:POJ 2886 Who Gets the Most Candies [题目]N个孩子顺时针坐成一个圆圈,从1~N编号,每个孩子手中有一张标有非零整数的卡片.第K个孩子先出圈,如果他手中卡片上的数字A>0,下一个出圈的是他左手边第A个孩子.A<0,下一个出圈的是他右手边第(-A)个孩子.第p个出圈的孩子会得到F(p)个糖果,F(p)为p的因子数.输出得到糖果数最多的孩子的名字及糖果数目. [思路]孩子数目很大(1~500000),于是想到要用线段树来优化,然后就是模拟出圈过程.并更新

CODEVS1282 约瑟夫问题(线段树)

题目描述 Description 有编号从1到N的N个小朋友在玩一种出圈的游戏.开始时N个小朋友围成一圈,编号为I+1的小朋友站在编号为I小朋友左边.编号为1的小朋友站在编号为N的小朋友左边.首先编号为1的小朋友开始报数,接着站在左边的小朋友顺序报数,直到数到某个数字M时就出圈.直到只剩下1个小朋友,则游戏完毕. 现在给定N,M,求N个小朋友的出圈顺序. 知识: 最近在做线段树,很是美丽.时间复杂度logn,空间大概在2*n到4*n左右(为避免溢出错误,就开到4*n吧,毕竟伤不起...)(1)单

[Codevs] 1282 约瑟夫问题

1282 约瑟夫问题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 题目描述 Description 有编号从1到N的N个小朋友在玩一种出圈的游戏.开始时N个小朋友围成一圈,编号为I+1的小朋友站在编号为I小朋友左边.编号为1的小朋友站在编号为N的小朋友左边.首先编号为1的小朋友开始报数,接着站在左边的小朋友顺序报数,直到数到某个数字M时就出圈.直到只剩下1个小朋友,则游戏完毕. 现在给定N,M,求N个小朋友的出圈顺序. 输入描述 Input Descri