【2018沈阳现场赛k】Let the Flames Begin

题意

有n个人围成一圈,编号1到n,从1号开始报数,每报到第k个,此人出列,下一个人再从1开始报数,求第m个出列的人的编号(n,m,k ≤ 1e18, m,k其中一个小于1e6)

分析

我们知道,约瑟夫环的出队是有O(n)的递推算法的:f(n) = (f(n-1)+k-1)%n 约瑟夫环数学推导

但是这里是最后一个出列的人的情况(n个人第n个出列)

考虑一下n个人第m个出列,设状态为f(n,m),我们可以假设在m个人中再插上n-m个人,他们都比前m个人晚出队(具体放在哪里不用关心,只要认为他们一定不会先出队就行了),那么递推式就和刚刚的雷同 f(n,m) = (f(n-1,m-1)+k-1)%n,这个式子可以在o(m)的时间内求出答案,适用于m≤1e6的情况

那么当m在1e18的范围内,该怎么办呢?

观察当前递推式,每次都是+k,当超过n的范围时,进行取模运算,可以发现,当k<<n时,在很多次递推操作中都是不需要取模的,而是只有+k操作,那么我们其实可以吧加法转化成乘法来加速

令add = n-m,考虑当前为f(x+add,x)执行t次后需要取模:

f(x+add+t,x+t) = (f(x+add,x) + (t*k)-1)%(x+add+t)+1

为什么这里的模数在一直变化,还可以这么干呢?因为模数每次只增加1,而f每次增加k,所以当k>1的时候,一定会越来越接近模数,直到超过它,当k=1的时候特判就好

计算t值:

一下简写f(x+add,x)为f

f + (t*k)-1 ≥ x+add+t

解得 t ≥ (x+add-f+1) / (k-1)

从这里也可以看出k=1是需要特判的

解出最小t,更新状态 x = x + t

这个复杂度我也不会算了,但感觉不会太大

代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll n,m,k;
 5 int main() {
 6     ios::sync_with_stdio(false);
 7     int _,ca=0;cin>>_;
 8     while(_--) {
 9         cin>>n>>m>>k;
10         ll ans = (k-1)%(n-m+1)+1;
11         if(k==1) ans = m;
12         else if(k >= m) {
13             for(ll i=2;i<=m;i++)
14                 ans = (ans + k -1)%(i+n-m)+1;
15         }
16         else {
17             ll now = 1;ll a = n-m;
18             while(now < m) {
19                 ll d = (ll)ceil((now + a - ans)*1.0/(k-1));
20                 if(d == 0) d++;
21                 if(now+d >= m) {   d = m-now;}
22                 now +=d;ll mod = (now+a);
23                 ans = (ans + k*d%mod-1+mod)%mod+1;
24             }
25         }
26         cout<<"Case #"<<++ca<<": "<<ans<<endl;
27     }
28 }

原文地址:https://www.cnblogs.com/greenty1208/p/9968462.html

时间: 2024-11-04 17:05:01

【2018沈阳现场赛k】Let the Flames Begin的相关文章

2018南京现场赛K 随机输出

题目链接:http://codeforces.com/gym/101981/attachments n和m太小,空地联通无环,总步数太大,直接随机输出5w个方向 #include<iostream> #include<algorithm> #include<ctime> using namespace std; int t,a,b,c,d,k; int main() { srand((unsigned)time(0)); int n,m; char op,ch[4]={

ACM-ICPC 2018 青岛赛区现场赛 K. Airdrop &amp;&amp; ZOJ 4068 (暴力)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4068 题意:吃鸡游戏简化为二维平面上有 n 个人 (xi,yi),空投的位置在 (x0,y0),每一秒所有人向靠近空投的位置走一步,四个方向有优先级先后(优先纵坐标),若已经在空投的位置则不变.往空投位置移动过程中,若两个或者更多人在同一点相遇(在空投相遇不算),则他们都死亡.给出空投的纵坐标,询问空投在所有横坐标中最少和最多存活的人数是多少. 题解:在最优情况

HDU5137 How Many Maos Does the Guanxi Worth (13广州现场赛K题 )--最短路问题

链接:click here 题意:从2~n-1这几个点中任意去掉一个点,使得从1到n的最短路径最大,如果任意去掉一个点1~n无通路输出Inf. 去年这道题现场是队友1A过的,感觉好NB,当时还不会最短路问题,只是脑子里大概有这么个印象,做了之发现数据比较水,今天看了一下Dijkstra 和Floyd,用两种算法实现了一下: 题目描述有点长,但是搞清楚了,就很容易了,因为数据实在很水,算是最短路入门训练的一道题了 Dijkstra 算法 (1)令S={源点s + 已经确定了最短路径的顶点vi} (

HDU 5122 K.Bro Sorting(2014北京区域赛现场赛K题 模拟)

这题定义了一种新的排序算法,就是把一串序列中的一个数,如果它右边的数比它小 则可以往右边移动,直到它右边的数字比它大为止. 易得,如果来模拟就是O(n^2)的效率,肯定不行 想了一想,这个问题可以被转化成 求这一串序列当中每个元素,它的右边是否存在小于它的数字,如果存在,则++ans 一开始没想到诶= = 不应该不应该 1 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler 2 #include <std

2013区域赛长沙赛区现场赛 K - Pocket Cube

K - Pocket Cube Time Limit:10000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4801 Description Pocket Cube is a 3-D combination puzzle. It is a 2 × 2 × 2 cube, which means it is constructed by 8 mini-cubes.

2013 长沙现场赛 K (Pocket Cube)

题意: 给出一个2X2X2的魔方,再给一个限定的步骤长度,不超过该长度最多能能使几个面拼成功. 纯粹模拟题,搞清楚几个面的变换关系,并化简步骤,三种旋转方式,两种旋转方向.bfs,dfs都可以. #include <stdio.h> #include <string.h> #define maxn 300000 int twist[3][3][4]= { {{1,7,17,21}, {3,13,19,23}, {9,8,14,15}}, {{2,11,17,8}, {3,5,16,

14牡丹江现场赛K zoj3829 Known Notation

Known Notation Time Limit: 2 Seconds      Memory Limit: 65536 KB Do you know reverse Polish notation (RPN)? It is a known notation in the area of mathematics and computer science. It is also known as postfix notation since every operator in an expres

2014ACM/ICPC亚洲区域赛牡丹江站现场赛-K ( ZOJ 3829 ) Known Notation

Known Notation Time Limit: 2 Seconds      Memory Limit: 65536 KB Do you know reverse Polish notation (RPN)? It is a known notation in the area of mathematics and computer science. It is also known as postfix notation since every operator in an expres

2014年ACM牡丹江赛区现场赛K题(ZOJ 3829)

Known Notation Time Limit: 2 Seconds      Memory Limit: 65536 KB Do you know reverse Polish notation (RPN)? It is a known notation in the area of mathematics and computer science. It is also known as postfix notation since every operator in an expres