题目地址:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11439
Time Limit:1000MS | Memory Limit:65536KB | 64bit IO Format:%I64d & %I64u |
Description
Background
During the latest war games (this story is fully described in the problem
"War games") the Minister of Defense of the Soviet Federation comrade Ivanov had a good chance to make sure personally, that an alertness of the Soviet Army under his command is just brilliant. But there was a thing, that continued to worry him. Being an outstanding commander, he realized, that only physical conditions of the soldiers were demonstrated. So the time came to organize one more war games and examine their mental capacity.
General Rascal was appointed to be responsible for the war games again. The general donated the allocated funds to the poor and went to bed free-hearted. In his dream, the tactics manual appeared to him and described a scheme, that allows to organize the war games absolutely free of charge.
Problem
In accordance with this scheme, the war games are divided into
N phases; and
N soldiers, successively numbered from 1 to
N, are marching round a circle one after another, i.e. the first follows the second, the second follows the third, ..., the (
N-1)-th follows the
N-th, and the
N-th follows the first. At each phase, a single soldier leaves the circle and goes to clean the WC, while the others continue to march. At some phase, the circle is left by a soldier, who is marching
K positions before the one, who left the circle at the previous phase. A soldier, whose number is
K, leaves the circle at the first phase.
Surely, Mr. Rascal cherished no hope about his soldiers' abilities to determine an order of leaving the circle. "These fools can not even paint the grass properly", - he sniffed scornfully and went to sergeant Filcher for an assistance.
Input
The only line contains the integer numbers
N (1 ≤
N ≤ 100000) and
K (1 ≤
K ≤
N).
Output
You should output the numbers of soldiers as they leave the circle. The numbers should be separated by single spaces.
Sample Input
input | output |
---|---|
5 3 | 3 1 5 2 4 |
Source
Problem Author: Ilya Grebnov, Nikita Rybak, Dmitry Kovalioff
Problem Source: Timus Top Coders: Third Challenge
Problem Source: Timus Top Coders: Third Challenge
按顺序输出出去的顺序
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=100010;
struct SBT
{
int left,right,size,key;
void init(int val)
{
left=right=0;
size=1;
key=val;
}
}tree[maxn];
int tot,root;
void left_rotate(int &x)
{
int y=tree[x].right;
tree[x].right=tree[y].left;
tree[y].left=x;
tree[y].size=tree[x].size;
tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
x=y;
}
void right_rotate(int &x)
{
int y=tree[x].left;
tree[x].left=tree[y].right;
tree[y].right=x;
tree[y].size=tree[x].size;
tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
x=y;
}
void maintain(int &x,int flag)
{
if(!flag)
{
if(tree[tree[tree[x].left].left].size>tree[tree[x].right].size)
right_rotate(x);
else if(tree[tree[tree[x].left].right].size>tree[tree[x].right].size)
left_rotate(tree[x].left),right_rotate(x);
else return;
}
else
{
if(tree[tree[tree[x].right].right].size>tree[tree[x].left].size)
left_rotate(x);
else if(tree[tree[tree[x].right].left].size>tree[tree[x].left].size)
right_rotate(tree[x].right),left_rotate(x);
else return;
}
maintain(tree[x].left,0);
maintain(tree[x].right,1);
maintain(x,0);
maintain(x,1);
}
//插入值为key的节点
void insert(int &x,int key)
{
if(!x)
{
x=++tot;
tree[x].init(key);
}
else
{
tree[x].size++;
if(key<tree[x].key)insert(tree[x].left,key);
else insert(tree[x].right,key);
maintain(x,key>=tree[x].key);
}
}
//删除值为key的节点
int del(int &x,int key)
{
if(!x)return 0;
tree[x].size--;
if(key==tree[x].key||(key<tree[x].key&&tree[x].left==0)||
(key>tree[x].key&&tree[x].right==0))
{
if(tree[x].left&&tree[x].right)
{
int p=del(tree[x].left,key+1);
tree[x].key=tree[p].key;
return p;
}
else
{
int p=x;
x=tree[x].left+tree[x].right;
return p;
}
}
else
return del(key<tree[x].key?tree[x].left:tree[x].right,key);
}
int get_kth(int x,int k)
{
if(k<=tree[tree[x].left].size)
return get_kth(tree[x].left,k);
else if(k>tree[tree[x].left].size+1)
return get_kth(tree[x].right,k-tree[tree[x].left].size-1);
return tree[x].key;
}
int N,K;
int main()
{
while(scanf("%d%d",&N,&K)!=EOF)
{
root=tot=0;
for(int i=1;i<=N;i++)insert(root,i);
bool first=true;
int last=1;
for(int i=1;i<=N;i++)
{
int k=(K+last-1)%tree[root].size;
if(!k)k=tree[root].size;
int tmp=get_kth(root,k);
if(first)first=false;
else printf(" ");
printf("%d",tmp);
del(root,tmp);
last=k;
}
printf("\n");
}
return 0;
}