首页 > 其他分享 >D. Soldier and Number Game

D. Soldier and Number Game

时间:2024-06-22 09:58:34浏览次数:21  
标签:prime std const int 质数 Number Soldier Game ans

题意:给出a和b(1 <= b <= a <= 5e6),问a!/b!变成1,最多要经过多少轮?没轮可以选择一个它的因子来除它。

思路:质因子数量,先线性筛,再质因子分解每个数,再前缀和,然后O1查询。

总结:在模板中使用范围质数筛选时,当范围到了5e6就MLE了,没法弄,最后用的线性筛+质因子分解。考虑要不要为模板中单独加一个统计范围内每个数的质因子数量的函数?

/*
 * PrimeNumberManipulator(质数类)
 * 设计思想:基于面向对象的思想的质数管理类。
 * 基于面向对象的编程思想,本方法尽可能多的隐藏了内部实现的细节,并且将必要的编程接口暴露在外部,并需要对这些接口进行直接的修改。
 *                             注意事项:第一个模板参数的数值必须是int型(在竞赛中范围最大是1e8)
 *                                      第二个模板参数是代表是否对第一个参数的范围内每个数进行质数统计(范围大概是1e6不会TLE)。
 *
 * gitHub(仓库地址): https://github.com/yxc-s/programming-template.git
 */












template<typename T, typename U>
class PrimeNumberManipulator{
public:
	template<typename V = T>
	using EnableIfInt    =   typename std::enable_if<std::is_same<V, int>::value, V>::type;
	using primeType      =   typename std::decay<decltype(T::value)>::type;
	using rangePrimeType =   typename std::decay<decltype(U::value)>::type;

	PrimeNumberManipulator(EnableIfInt<primeType>* = 0, EnableIfInt<rangePrimeType>* = 0 ){
		sievePrimes();
		getRangePrimes();
	}

	const std::vector<int>& getPrimeArray() const {
		return prime_values_;
	}

	const std::vector<std::vector<std::pair<int, int>>>& getRangePrimesArray() const {
		return range_prime_values_;
	}

	/* 获取单个数的质因子及出现次数 */
	template <typename V>
	std::vector<std::pair<V, int>> getUniquePrimes(V x){
		std::vector<std::pair<V, int>> res;
		for (const auto& prime : prime_values_){
			if (1ll * prime * prime > x){
				break;
			}
			int cnt = 0;
			while (x % prime == 0){
				x /= prime;
				cnt ++;
			}
			if (cnt){
				res.emplace_back(prime, cnt);
			}
		}
		if (x > 1){
			res.emplace_back(x, 1);
		}
		return res;
	}

	/* 统计不同的质数个数 */
	template<typename V>
	int countUniquePrimes(V x){
		int ans = 0;
		for (const auto& prime : prime_values_){
			if (prime > x / prime){
				break;
			}
			ans ++;
			while (x % prime == 0){
				x /= prime;
			}
		 }
		return ans + (x > 1);
	}

	/* 统计所有的质数 */
	template<typename V>
	int countAllPrimes(V x){
		int ans = 0;
		for (const auto& prime : prime_values_){
			if (prime > x / prime){
				break;
			}
			while (x % prime == 0){
				x /= prime;
				ans ++;
			}
		}
		return ans + (x > 1);
	}

	/* 判定质数,当筛选范围为1e8时,最多可判断1e16的质数*/
	template<typename V>
	bool isPrime(V x){
		if (x <= getPrimeLimit()){
			return bs_[x];
		}
		for (const auto& prime : prime_values_){
			if (x % prime == 0){
				return false;
			}
		}
		return true;
	}

	/* 统计因子数量 */
	template<typename V>
	int countDivisors(V x){
		int ans = 1;
		for (const auto& prime : prime_values_){
			if (prime > x / prime){
				break;
			}
			int power = 0;
			while (x % prime == 0){
				x /= prime;
				power ++;
			}
			ans *= power + 1;
		}
		return x > 1 ? ans * 2 : ans;
	}


private:
	std::bitset<100000010>                            bs_;
	std::vector<int>                                  prime_values_;
	std::vector<std::vector<std::pair<int, int>>>     range_prime_values_;


private:
	constexpr primeType      getPrimeLimit()      { return T::value; }
	constexpr rangePrimeType getRangePrimeLimit() { return U::value; }
	/* 线性筛 */
	void sievePrimes(){
		bs_.set();
		bs_[0] = bs_[1] = 0;
		for (int i = 2; i <= getPrimeLimit(); ++i){
			if (bs_[i]){
				prime_values_.emplace_back(i);
			}
			for (const auto& prime : prime_values_){
				if (1ll * i * prime > getPrimeLimit()){
					break;
				}
				bs_[i * prime] = 0;
				if (i % prime == 0){
					break;
				}
			}
		}
	}

	/* 获取[1, x]范围内每个数的质因子及其出现次数*/
	void getRangePrimes(){
		range_prime_values_.resize(getRangePrimeLimit() + 1);
		for (int i = 2; i <= getRangePrimeLimit(); ++i){
			if (range_prime_values_[i].empty()){
				for (int j = i; j <= getRangePrimeLimit(); j += i){
					int cnt = 0;
					int num = j; 
					while (num % i == 0){
						cnt ++;
						num /= i;
					}
					range_prime_values_[j].emplace_back(i, cnt);
				}
			}
		}
	}


};


constexpr int N = (int)5e6;
constexpr int  PRIME_VALUE_LIMIT   =   N + 10;              /*最多可以到1e8*/
constexpr int  RANGE_VALUE_LIMIT   =   0;        /*目测最多到1e6*/
using Primer = PrimeNumberManipulator<std::integral_constant<decltype(PRIME_VALUE_LIMIT), PRIME_VALUE_LIMIT>, 
									 std::integral_constant<decltype(PRIME_VALUE_LIMIT), RANGE_VALUE_LIMIT>>;

Primer primer;
const std::vector<int>&                              primes = primer.getPrimeArray();
const std::vector<std::vector<std::pair<int, int>>>& range_primes = primer.getRangePrimesArray();

/*
TODO: 第二个模板参数要不要也换成跟第一个模板参数相同的类型,来单独进行筛选?
	  将大质数的算法也写进去。
	   欧拉函数,莫比乌斯函数。
*/

using namespace std;
array<int, N + 20> pref{};
void preProcess(){
	for (int i = 1; i <= N; ++i){
		pref[i] = pref[i - 1] + primer.countAllPrimes(i);
	}
}




void solve(){
	int a, b;
	cin >> a >> b;
	cout << (pref[a] - pref[b]) << '\n';
}

标签:prime,std,const,int,质数,Number,Soldier,Game,ans
From: https://www.cnblogs.com/yxcblogs/p/18261899

相关文章

  • 【流星蝴蝶剑game】
    由于《流星蝴蝶剑》是一款较旧的游戏,而且我无法提供受版权保护的游戏的代码,我将提供一个简单的2D游戏编程实例,以展示如何使用Unity引擎和C#语言来创建一个基本的游戏。这个例子将涉及到创建一个玩家角色,使其能够移动并收集物品。首先,确保你已经安装了UnityHub和Unity编辑......
  • 基于Python中的tkinter和pygame库创建一个简单音乐播放器
    importosimporttimeimporttkinterastkfromtkinterimportfiledialog,messagebox,ttkimportpygameimportmutagen.mp3#用于获取MP3文件时长classMusicPlayer:def__init__(self,root):pygame.init()self.root=rootsel......
  • QOJ1285 Stirling Number
    QOJ传送门因为\(x^{\overlinep}\equivx^p-x\pmodp\),所以设\(n=pq+r\),其中\(r\in[0,p-1]\),则有:\[\begin{aligned}x^{\overlinen}&=(\prod\limits_{i=0}^{q-1}(x+ip)^{\overlinep})(x+pq)^{\overliner}\\&=(x^p......
  • 【洗头发game】
    如果您想要编写一个简单的洗头发游戏代码,可以使用Python来实现。下面是一个简单的示例代码,它模拟了一个简单的洗头发过程,包括选择洗发水、冲洗和吹干头发。这个代码仅供参考和学习使用。importrandomdefchoose_shampoo():shampoos=["去屑洗发水","滋养洗发水",......
  • [HGAME 2023 week3]kunmusicin
    这道题挺好玩的,坑了我几下,记录一下题目下载得到3个文件 exe打开,不同按钮发出不同声音,除此之外就没有其他东西了 exe-Dieexe-IDAmain函数,没有找到“唱”“跳”“篮球”之类的关键字符串因为爆红,所以动调了一下,也没发现什么东西 string窗口也没有找到关键词语 ......
  • Infinite Card Game
    无限纸牌游戏题目描述Monocarp和Bicarp正在玩一个纸牌游戏。每张牌都有两个参数:攻击值和防御值。如果一张牌$s$的攻击值严格大于$t$的防御值,那么这张牌$s$就能打败另一张牌$t$。Monocarp有$n$张牌,其中第\(i\)张牌的攻击值为$\mathit{ax}_i$,防御值......
  • GameFrameWork框架初学随笔其一
    边看边分析,学习记录用Setting用来存储游戏数据,游戏存档可以用AB包的后缀名来存储不同语言的资源?Procedure的调用顺序,OnInit(不管有没有调用到,都会在游戏初始化时调用),OnEnter,OnUpdate,OnLevel,OnDestroy如果不是EditorResourceMode模式,单机模式需要初始化下AssetBundle资源,关......
  • LeetCode 2268. Minimum Number of Keypresses
    原题链接在这里:https://leetcode.com/problems/minimum-number-of-keypresses/description/题目:Youhaveakeypadwith 9 buttons,numberedfrom 1 to 9,eachmappedtolowercaseEnglishletters.Youcanchoosewhichcharacterseachbuttonismatchedtoaslong......
  • CF1267G Game Relics
    GameRelics首先猜一下(在\(x\lec_i\)的条件下),应该先抽奖,后剩下的全买考虑已经拥有了\(k\)个圣物,再又有一个圣物的期望代价为\(E(X)=\frac{n-k}{n}x+\frac{k}{n}(E(X)+\frac{x}{2})\)\(E(X)=x(1+\frac{k}{2(n-k)})\)随着随机选择,设还剩\(k\)个圣物没有,其代价和为......
  • World Tour Finals 2022 Day2 E: Adjacent Xor Game
    考虑从高到低位做,不断贪心的一个过程。即假设把当前所有数\(a_i\)看成\(\lfloor\frac{a_i}{2^d}\rfloor\),有当前最优答案\(ans_d\);现在把所有数看成\(\lfloor\frac{a_i}{2^{d-1}}\rfloor\),推出下一步的答案\(ans_{d-1}\)。假设\(/2^d\)时,每一步xor完的序列是\(a_1......