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
 
将约瑟夫环拉成一条直线,一开始一共n个人,每次从第一个人开始(杀掉第一个)从前向后依次每隔k个人杀一个人,最后大家都被干掉了,然后就形成了一个死亡序列
有m次询问,问你在死亡序列中的第x个人编号是多少.
 
思路:
如果我们把他们的下标从0开始,那么第一批死的人下标肯定满足i%k==0
继续想,杀掉一批人以后活着的人会向前补空位,加上第i个人在这轮没有被杀,那么他下轮的位置就会在i-i/k-1.
换句话说第i个人会比第i-i/k-1多活一轮
然后我们发现我们花O(n)的时间就能递推出每个人是在第几轮的第几个死的.
我们开一个pair 保存每个人是 第几轮 和第几个
我们再对轮数取个前缀和.就能知道他在总队列里面是第几个了
一开始想到补空位的想法了,但是没有深想,利用递推的思路,其实在线性时间内就可以求出答案了
代码如下:
 #include <bits/stdc++.h>

 using namespace std;
const int maxn=3e6+;
int cnt[maxn];
int ans[maxn];//最后的答案
int n,k,q;
pair<int,int> dp[maxn];
int main()
{
//freopen("de.txt","r",stdin);
int t;
scanf("%d",&t);
while (t--){
scanf("%d%d%d",&n,&k,&q);
memset(cnt,,sizeof cnt);
for (int i=;i<n;++i){
dp[i].first=i%k?(dp[i-i/k-].first+):;
dp[i].second=cnt[dp[i].first]++;//求出来第i人的轮数,相应轮数cnt++
}
for (int i=;i<maxn;++i){
if (cnt[i]==)
break;
cnt[i]+=cnt[i-];//处理前缀和,即第i轮之前一共杀死多少人
}
for (int i=;i<n;++i){
ans[(dp[i].first?cnt[dp[i].first-]:)+dp[i].second]=i;
}
for (int i=;i<q;++i){
int x;
scanf("%d",&x);
printf("%d\n",ans[x-]+);
}
}
return ;
}

hdu 5860 Death Sequence(递推+脑洞)的更多相关文章

  1. HDU 5860 Death Sequence(递推)

    HDU 5860 Death Sequence(递推) 题目链接http://acm.split.hdu.edu.cn/showproblem.php?pid=5860 Description You ...

  2. HDU 5860 Death Sequence(死亡序列)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  3. HDU 5950 Recursive sequence 递推转矩阵

    Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  4. hdu 5950 Recursive sequence 递推式 矩阵快速幂

    题目链接 题意 给定\(c_0,c_1,求c_n(c_0,c_1,n\lt 2^{31})\),递推公式为 \[c_i=c_{i-1}+2c_{i-2}+i^4\] 思路 参考 将递推式改写\[\be ...

  5. 2016 Multi-University Training Contest 10 || hdu 5860 Death Sequence(递推+单线约瑟夫问题)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5860 题目大意:给你n个人排成一列编号,每次杀第一个人第i×k+1个人一直杀到没的杀.然后 ...

  6. HDU 5860 Death Sequence

    用线段树可以算出序列.然后o(1)询问. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<c ...

  7. HDU 2085 核反应堆 --- 简单递推

    HDU 2085 核反应堆 /* HDU 2085 核反应堆 --- 简单递推 */ #include <cstdio> ; long long a[N], b[N]; //a表示高能质点 ...

  8. hdu-5496 Beauty of Sequence(递推)

    题目链接: Beauty of Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java ...

  9. hdu 2604 Queuing(dp递推)

    昨晚搞的第二道矩阵快速幂,一开始我还想直接套个矩阵上去(原谅哥模板题做多了),后来看清楚题意后觉得有点像之前做的数位dp的水题,于是就用数位dp的方法去分析,推了好一会总算推出它的递推关系式了(还是菜 ...

随机推荐

  1. spark streaming简单示例

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  2. BZOJ 5296: [Cqoi2018]破解D-H协议(BSGS)

    传送门 解题思路 \(BSGS\)裸题??要求的是\(g^a =A (mod\) \(p)\),设\(m\)为\(\sqrt p\),那么可以设\(a=i*m-j\),式子变成 \[ g^{i*m-j ...

  3. react教程 — redux

    一.概念:             http://caibaojian.com/react/redux-basic.html   或  https://www.cnblogs.com/maopixin ...

  4. Union比or快 Using UNION is faster when it comes to cases like scan two different column。

    problem: 595. Big Countries A country is big if it has an area of bigger than 3 million square km or ...

  5. 老牌激活工具 — Microsoft Toolkit 2.5.1正式版【转】

    老牌激活工具 — Microsoft Toolkit 2.5.1正式版  Microsoft Toolkit 2.5.1是一个一键激活MS Office 及 win系统的工具.原理就是利用KMS来激活 ...

  6. 汇编指令MOV

    格式:MOV DST,SRC 例如: MOV EAX,#050aH ;将十六进制050a 传送到通用寄存器eax中 MOV DI,BX(寄存器到寄存器之间传数) MOV ES,AX(通用寄存器与段寄存 ...

  7. LeetCode:旋转数组

    最近看了一道题,自己做个过后又参考了网上的解法,为了加深对这个解法的理解和记忆于是有了这篇博客,供自己以后复习用 题目: 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数. 示例 ...

  8. CommonJS规范 by ranyifeng

    1,概述 CommonJS是服务器端模块的规范,Node.js采用了这个规范. 根据CommonJS规范,一个单独的文件就是一个模块.加载模块使用require方法,该方法读取一个文件并执行,最后返回 ...

  9. 网关中加入熔断机制(Hystrix)

    网关中加入熔断机制 在网关中加入熔断机制 添加依赖项 spring-cloud-gateway项目POM文件加入spring-cloud-starter-netflix-hystrix <dep ...

  10. python基础--新式类实现单例模式

    在网上看了有关python实现单例模式的博客,发现好多都是转载的,并且都是按照python2.x版本旧式类的方式写的. 虽然也能读懂,但对于我这种一开始学的就是python3.x的新手来说,心里总有点 ...