zoukankan      html  css  js  c++  java
  • 约瑟夫问题O(n)/O(mlogn)

    题面

    题解

    约瑟夫问题。编号00~n1n-1,每次拿第mm个。

    O(n)O(n)f[n]f[n]表示幸存的人的编号,f[n]=(f[n1]+m)%nf[n]=(f[n-1]+m)\%n

    O(mlogn)O(mlogn):优化:把若干连续的mm一起计算,直到加起来的值达到第一个模数nn,然后进行下一次。每次的时间与O(n/m)O(n/m)有关,所以总时间复杂度大概可能是O(mlogn)O(mlog n)的。

    假设当前答案是ansans,位置是ii,一起求的个数为kk,则:
    ans+kmi+k1ans+kmgeq i+k-1移项就是ki1ansm1kgeq lceil{frac{i-1-ans}{m-1} ceil}

    CODE

    #include <bits/stdc++.h>
    using namespace std;
    int T, n, m;
    int main () {
    	scanf("%d", &T); while(T--) {
    		scanf("%d%d", &n, &m);
    		if(m == 1) { printf("%d
    ", n); continue; }
    		int ans = 0;
    		for(int i = 1; i <= n && i <= m; ++i)
    			ans = (ans + m) % i;
    		for(int i = m+1, j; i <= n; i = j+1) {
    			j = min(i + (i-1-ans+m-2)/(m-1) - 1, n);
    			ans = (ans + 1ll*m*(j-i+1)) % j;
    		}
    		printf("%d
    ", ans+1); //题目中要求的编号是1~n,所以+1
    	}
    }
    
  • 相关阅读:
    刷题(十五)
    Pycharm按装
    Jmeter
    内存泄露部分检测工具
    Failed to resolve
    图片显示方向不对怎么办
    ScaleType属性
    RobotFramework
    LoadRunner
    Appium
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039192.html
Copyright © 2011-2022 走看看