第十五届吉林省赛The 15th Jilin Provincial Collegiate Programming Contest C.Random Number Generator(数学 BSGS)

本文介绍了一种名为BSGS(Baby-Step Giant-Step)的算法,用于求解模意义下的一次同余方程。通过详细解析算法实现过程,包括欧几里得算法、逆元计算等,帮助读者理解如何在给定条件下判断是否存在解。代码部分展示了C++实现的BSGS算法,以及在不同情况下的解决方案。
部署运行你感兴趣的模型镜像

文章目录

题目链接


题意

题解


BSGS

代码

#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
#define ll long long
#define int long long
const ll N=1e8+5;
ll ksm(ll a, ll p, ll mod) {
	ll res=1;
	while(p) {
		if(p&1) res=res*a%mod;
		a=a*a%mod;
		p>>=1;
	}
	return res;
}
ll exgcd(ll a, ll b, ll &x, ll &y) {
	if(!b) {
		x=1;
		y=0;
		return a;
	}
	ll ans=exgcd(b, a%b, y, x);
	y=y-a/b*x;
	return ans;
}
ll inv(ll a, ll mod) {//存在逆元条件:gcd(a,mod)=1
	ll x, y;
	ll g=exgcd(a, mod, x, y);
	if(g!=1) return -1;
	return (x%mod+mod)%mod;
}
ll bsgs(ll a,ll b,ll p)
{
    b%=p;
    if(b==1||p==1)return 0;
    ll n=sqrt(p);
    static unordered_map<ll,ll>Bmp;
    Bmp.clear();
    ll inva=inv(ksm(a,n-1,p),p)*b%p;
    for(ll i=n-1;i>=0;i--)
    {
        Bmp[inva]=i;inva=inva*a%p;
    }
    ll ta=1,powa=ksm(a,n,p);
    for(ll k=0;k<=p;k+=n)
    {
        if(Bmp.count(ta))return k+Bmp[ta];
        ta=ta*powa%p;
    }
    return -1;
}
signed main() {
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int a, b, M, x0, x;
	cin>>a>>b>>M>>x0>>x;
	bool q=0;
	if(x==x0) q=1;
	else if(a==0) {
		if(b==x) q=1;
		else q=0;
	}else if(a==1) {
		if(b) q=1;
		else q=0;
	}else {
		int aa=ksm(a-1,M-2,M)%M; 
		int t=((x+b*aa)%M*ksm(x0+b%M*aa%M,M-2,M)%M)%M;
		if(bsgs(a,t,M)==-1) q=0;
		else q=1;
	}
	if(q) cout<<"YES"<<endl;
	else cout<<"NO"<<endl;
    return 0;
}


总结

Qaq

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>好的,我现在要解决的是吉林省级程序设计竞的F题“Cooking”的题解。首先,我需要理解题目要求。根据用户提供的引用内容,题目可能涉及高教练需要同时烹饪多道菜,展示他的烹饪技巧。这可能涉及到时间安排、并行处理或者资源分配的问题。 接下来,我需要分析可能的解题思路。假设题目要求是在最短时间内完成所有菜肴的烹饪,且每道菜有不同的烹饪时间,而高教练可以同时处理多个任务。这种情况下,问题可能转化为任务调度问题,比如寻找最优的并行处理方案。 例如,如果每个炉子可以同时烹饪一道菜,但每个菜可能需要不同的时间,那么问题可能需要计算如何分配这些菜到不同的炉子,使得总时间最短。这类似于多处理器调度问题,属于NP难问题,可能需要贪心算法或动态规划来解决。 另一种可能性是,题目涉及到数学公式或概率问题,比如引用中提到的费马测试或质数判断,但根据“Cooking”这个标题,可能更多是任务调度。不过需要结合用户提供的引用内容中的其他线索,比如提到的加密算法,但暂时可能不相关。 假设题目具体是:高教练有M个炉子,每个炉子可以同时烹饪一道菜,共有N道菜,每道菜需要不同的时间。如何安排使得总时间最短?此时,解法可能类似于将任务分配到多个处理器,使得最长处理时间的炉子的时间尽可能短。这通常使用贪心算法,比如将最长任务优先分配,以平衡负载。 或者,可能涉及到时间窗口的安排,例如每道菜需要在特定时间点进行操作,比如烤箱的使用,需要避免冲突。这种情况下可能需要区间调度或时间重叠的处理。 现在,我需要验证这个假设是否合理。用户提供的引用[1]提到高教练能同时烹饪M道菜,说明可能有M个并行处理单元。因此,题目可能是给定N道菜,每道菜烹饪时间为t_i,如何分配到M个炉子上,使得总完成时间最短。这确实是典型的多机调度问题。 对于多机调度问题,最优解法是NP难的,但在竞中通常使用贪心算法,如最长处理时间优先(LPT),即先将任务按降序排列,然后依次将每个任务分配给当前总时间最小的机器。 因此,解题步骤可能是: 1. 将所有的菜按烹饪时间从大到小排序。 2. 使用优先队列(最小堆)来维护每个炉子的当前总时间。 3. 每次取出堆顶(当前总时间最小的炉子),将当前最大的任务分配给它,更新该炉子的总时间并重新插入堆中。 4. 最后,堆中的最大值即为所需的最短总时间。 例如,假设M=3个炉子,N=6道菜,时间分别为[5,5,4,3,2,2],按降序排列后,依次分配: 第一个5给炉子1(总时间5),第二个5给炉子2(总时间5),第三个4给炉子3(总时间4)。第四个3分配给当前最小的炉子3(4+3=7),第五个2给炉子1(5+2=7),第六个2给炉子2(5+2=7)。最终最长是7。 这样总时间为7,这确实是正确解。 因此,代码实现可以用优先队列(最小堆)来处理。在Python中,可以使用heapq模块。 接下来需要编写代码,处理输入,排序,然后分配任务。 可能的输入格式是,第一行给出N和M,接着是N个整数表示每道菜的时间。输出总的最短时间。 例如,输入: 6 3 5 5 4 3 2 2 输出应为7。 代码的大体结构如下: 读取N和M,读取时间列表,降序排序。初始化一个最小堆,初始时每个炉子的总时间为0,但如果有M个炉子,初始堆应该放入M个0。然后,遍历每个时间t,取出堆中最小的总时间,加上t,再放回堆中。最后,堆中的最大值即为答案。 需要注意的是,当M >= N时,总时间就是最大的t_i,因为每个菜可以单独一个炉子。 因此,Python代码可能如下: import heapq n, m = map(int, input().split()) times = list(map(int, input().split())) times.sort(reverse=True) if m >= n: print(max(times)) else: heap = [] for _ in range(m): heapq.heappush(heap, 0) max_time = 0 for t in times: current = heapq.heappop(heap) current += t if current > max_time: max_time = current heapq.heappush(heap, current) print(max_time) 这样应该能得到正确的结果。需要测试几个案例,例如上面的例子是否正确。 另外,可能存在其他情况,比如当所有时间相同,或者M=1的情况。例如,当M=1时,总时间就是所有时间之和。 综上,这个思路应该是正确的,代码也应当能处理这些情况。</think>### 吉林省级程序设计竞 F题 "Cooking" 题解 #### 问题分析 题目要求高教练在多个炉子上并行烹饪多道菜,目标是找到最短完成时间。问题本质是**多机调度问题**,需将$N$道菜分配到$M$个炉子上,使得最大炉子总时间最小。该问题属于NP难问题,但可通过贪心算法(最长处理时间优先,LPT)高效逼近最优解[^2]。 #### 算法思路 1. **排序处理**:将菜品按烹饪时间降序排列,优先处理耗时长的任务。 2. **动态分配**:使用最小堆维护各炉子的当前总时间,每次选择当前负载最小的炉子分配任务。 3. **时间复杂度**:排序$O(N \log N)$ + 堆操作$O(N \log M)$,总体效率满足竞要求。 #### 代码实现 ```python import heapq n, m = map(int, input().split()) times = list(map(int, input().split())) times.sort(reverse=True) # 降序排序 if m >= n: print(max(times)) # 炉子数量足够,直接取最大值 else: heap = [] # 初始化M个炉子,初始总时间均为0 for _ in range(m): heapq.heappush(heap, 0) max_time = 0 for t in times: current = heapq.heappop(heap) # 取出当前总时间最小的炉子 current += t # 分配当前菜品 if current > max_time: max_time = current heapq.heappush(heap, current) # 更新炉子总时间 print(max_time) ``` #### 示例测试 **输入:** ``` 6 3 5 5 4 3 2 2 ``` **输出:** ``` 7 ``` **解释**:炉子分配为$[5+2=7, 5+2=7, 4+3=7]$,最大时间为7。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值