| 题目链接 | 难度等级 | 完成状态 | 完成分数 | 最后编辑时间 | 失误原因(初次提交分数) |
|---|---|---|---|---|---|
| 约瑟夫问题 | ★☆☆☆☆ | 答案正确 | 100 | 2015-3-29 21:26:45 | 数组不够大(40) |
N个小朋友围一圈,每次点到第k个出列,问出列顺序。
原始编号 i 1 2 3 4 5 i' 1 2 3 4 5 p 1 1 1 1 1 剔除掉第3个小朋友的编号 i 1 2 3 4 5 i' 1 2 x 3 4 p 1 1 0 1 1
容易知道i'是p的前缀和。可以用线段树处理问题。
| 1282.cpp代码已折叠
展开折叠内容
|
|---|
#include<stdio.h>
#include<algorithm>
using namespace std;
template<size_t N>
class SegmentTree
{
//模板:线段树//
public:
int tree[N];
int lazy[N];
#define lchild rt << 1, l, m
#define rchild rt << 1 | 1, m + 1, r
void push_up(int rt) {
tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}
int build(int rt,int l,int r,int ex)
{
if(l==r)
{ if(ex!=l)
return tree[rt]=1;
else
return tree[rt]=1e+7;
}
int m=(l+r)>>1;
return tree[rt]=build(lchild,ex)+build(rchild,ex);
}
void push_down(int rt, int len) {
tree[rt << 1] += lazy[rt] * (len - (len >> 1));
lazy[rt << 1] += lazy[rt];
tree[rt << 1 | 1] += lazy[rt] * (len >> 1);
lazy[rt << 1 | 1] += lazy[rt];
lazy[rt] = 0;
}
void push_down(int rt) {
tree[rt << 1] += lazy[rt];
lazy[rt << 1] += lazy[rt];
tree[rt << 1 | 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
lazy[rt] = 0;
}
void update(int L, int R, int delta, int rt , int l , int r ) {
if (L <= l && r <= R) {
tree[rt] += delta * (r - l + 1);
lazy[rt] += delta;
return;
}
if (lazy[rt]) push_down(rt, r - l + 1);
int m = (l + r) >> 1;
if (L <= m) update(L, R, delta, lchild);
if (R > m) update(L, R, delta, rchild);
push_up(rt);
}
int query(int L, int R, int rt , int l , int r ) {
if (L <= l && r <= R) return tree[rt];
if (lazy[rt]) push_down(rt, r - l + 1);
int m = (l + r) >> 1, ret = 0;
if (L <= m) ret += query(L, R, lchild);
if (R > m) ret += query(L, R, rchild);
return ret;
}
};
SegmentTree<33333> tre={};
int n,k;
int biSearch(int l,int r,int last)
{
if(l==r)return l;
if(r<=0)return -1e+6;
if(tre.query(1,m,1,1,n+1)<last)
return biSearch(m+1,r,last);
else
return biSearch(l,m,last);
}
int main()
{
scanf("%d%d",&n,&k);
tre.build(1,1,n+1,n+1);
int last=0,least=n,lasti;
for(int i=1;i<=n;++i,--least)
{
last=(last+k-1)%least+1;
lasti=biSearch(1,n+1,last);
tre.update(lasti,lasti,-1,1,1,n+1);
printf("%d ",lasti);
--last;
}
}
|