题目链接:

Death Sequence

Time Limit: 16000/8000 MS (Java/Others)   

 Memory Limit: 65536/65536 K (Java/Others)



Problem Description
You may heard of the Joseph Problem, the story comes from a Jewish historian living in 1st century. He and his 40 comrade soldiers were trapped in a cave, the exit of which was blocked by Romans. They chose suicide over capture and decided that they would form a circle and start killing themselves using a step of three. Josephus states that by luck or maybe by the hand of God, he and another man remained the last and gave up to the Romans.

Now the problem is much easier: we have N men stand in a line and labeled from 1 to N, for each round, we choose the first man, the k+1-th one, the 2*k+1-th one and so on, until the end of the line. These poor guys will be kicked out of the line and we will execute them immediately (may be head chop, or just shoot them, whatever), and then we start the next round with the remaining guys. The little difference between the Romans and us is, in our version of story, NO ONE SURVIVES. Your goal is to find out the death sequence of the man.

For example, we have N = 7 prisoners, and we decided to kill every k=2 people in the line. At the beginning, the line looks like this:

1 2 3 4 5 6 7

after the first round, 1 3 5 7 will be executed, we have

2 4 6

and then, we will kill 2 6 in the second round. At last 4 will be executed. So, you need to output 1 3 5 7 2 6 4. Easy, right?

But the output maybe too large, we will give you Q queries, each one contains a number m, you need to tell me the m-th number in the death sequence.
 

 

Input
Multiple cases. The first line contains a number T, means the number of test case. For every case, there will be three integers N (1<=N<=3000000), K(1<=K), and Q(1<=Q<=1000000), which indicate the number of prisoners, the step length of killing, and the number of query. Next Q lines, each line contains one number m(1<=m<=n).
 

 

Output
For each query m, output the m-th number in the death sequence.
 

 

Sample Input
1
7 2 7
1
2
3
4
5
6
7
 

 

Sample Output
1
3
5
7
2
6
4
题意:
 
约瑟夫问题的变形,从头开始每k个去掉一个数,到了末尾后才从头开始,得到的序列各个数是多少;
 
思路:
 
左移一位,变成[0,n-1],现在对于i如果i%k==0那么这个数在第一轮中就被去除,p[i].first=1,p[i].second=i/k+1表示第po[i].first轮第p[i].second个被去除;
如果i%k!=0,那么这个数在下一轮中就会变成i-i/k-1;i-i/k-1<i,所以直接从小到大扫一遍就可以,O(n)的复杂度, 就是这样就好了;
 
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bits/stdc++.h>
#include <stack>
#include <map>
 
using namespace std;
 
#define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss));
 
typedef  long long LL;
 
template<class T> void read(T&num) {
    char CH; bool F=false;
    for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar());
    for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar());
    F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
    if(!p) { puts("0"); return; }
    while(p) stk[++ tp] = p%10, p/=10;
    while(tp) putchar(stk[tp--] + '0');
    putchar('\n');
}
 
const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=1e9;
const int N=3e6+10;
const int maxn=1e4+220;
const double eps=1e-12;

int n,k,q,ans[N],sum[N],high;
pair<int,int>p[N];
inline void counter(int x)
{
    if(x%k==0)p[x].first=1,p[x].second=x/k;
    else p[x].first=p[x-x/k-1].first+1,p[x].second=p[x-x/k-1].second;
    sum[p[x].first]++;
    high=max(high,p[x].first);
}
inline void Init()
{
    high=0;
    for(int i=0;i<=n;i++)sum[i]=0;
    for(int i=0;i<n;i++)counter(i);
    for(int i=1;i<=high;i++)sum[i]+=sum[i-1];
    for(int i=0;i<n;i++)
    {
        int temp=sum[p[i].first-1]+p[i].second+1;
        ans[temp]=i+1;
    }
}
int main()
{
   int t;
   read(t);
   while(t--)
   {
        read(n);read(k);read(q);
        Init();
        int x;
        while(q--)
        {
            read(x);
            print(ans[x]);
        }
   }
    return 0;
}