zoukankan      html  css  js  c++  java
  • 【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 }
  • 相关阅读:
    笔记:多线程访问ConcurrentHashMap对key加锁
    根据第三列去重
    Correct the classpath of your application so that it contains a single, compatible version of org.apache.log4j.ConsoleAppender
    python 中将源配置为阿里
    criteria两个 判断
    git flow
    sqlmap用法详解
    MongoDB 入门
    MongoDB 手册
    OWASP TOP 10简单介绍
  • 原文地址:https://www.cnblogs.com/greenty1208/p/9968462.html
Copyright © 2011-2022 走看看