Description
There are n children numbered from 1 to N playing an out-of-the-loop game. At the beginning, n children in a circle, numbered i+1 children standing on the left of the number I children. The child numbered 1 stands on the left of the child numbered n. The first number of children numbered 1 began to count off, and then stood on the left side of the children in sequence, until a number to a number m out of the circle. Until there are only 1 children left, the game is complete.
Now given the n,m, ask N children to make a circle of the order. Input
The only row contains two integer n,m. (1<=n,m<=30000) Output
The only row contains n integers, separated by a space for each of the two integers, and the first integer denotes the number of the child who circled the first I. Sample Input
5 3 Sample Output
3 1 5) 2 4
A very classical problem, pure analog words time complexity will reach O (nm), obviously will tle.
The timeout is mainly determined by the M in O (nm), because we are the simulation, looking for an out-of-circle children need one to determine whether the ring, but in fact we do not need, we just have to maintain a fast prefix and the data structure, line tree and tree array can do this.
Why do we have a prefix and we can quickly find the next kid's place, because
Current child prefixes and -1+m= next to a child prefix and
The above is missing the operation of the remaining children.
Use k to represent the current circle of children's prefix and, the next child's prefix and by the following methods to find out.
k= (k-1+m-1)% (n-i+1) +1 (initialized to K=1, which represents the No. 0 circle of children's prefixes and, without practical significance)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace
Std
const int N=30000+10;
int n,m,k,tmp;
int t[n];
int lowbit (int x) {return x& (-X);}
int sum (int pos,int x) {int tmp=0;
while (pos>0) {Tmp+=t[pos];
Pos-=lowbit (x);
}} void Add (int pos,int x) {while (pos<=n) {t[pos]+=x;
Pos+=lowbit (x);
}}/*int Search (int l,int r,int x) {int m= (L+R)/2;
if (l==r) return l;
if (X<=t[m]) return search (l,m,x);
else return search (m+1,r,x);
}*/int main () {//freopen ("In.txt", "R", stdin);
Freopen ("OUT.txt", "w", stdout);
cin>>n>>m;
for (int i=1;i<=n;i++) Add (i,1);
k=1;
for (int i=1;i<=n;i++) {k= (k-1+m-1)% (n-i+1) +1;
Tmp=lower_bound (t+1,t+n,k)-t;
Add (tmp,-1);
if (i!=n) cout<<tmp<< ";
else cout<<tmp<<endl;
} return 0; }
Ps_0: The program has a time complexity of O (Nlogn).
Ps_1: If you just ask for the last child's number, there is an O (n) algorithm.