【GMOJ7177】鱼跃龙门
时间:2021-07-15
本文章向大家介绍【GMOJ7177】鱼跃龙门,主要包括【GMOJ7177】鱼跃龙门使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目
题目链接:https://gmoj.net/senior/#main/show/7177
求一个最小的 \(k\) 使得 \(\left(\sum^{k}_{i=1}i\right)\bmod n=0\)。多测。
\(Q\leq 100,n\leq 10^{12}\)。
思路
也就是找一个最小的 \(k\) 使得 \(2n|k(k+1)\)。下面令 \(n\gets 2n\)。
那么一定是将 \(n\) 分解成 \(n=a\times b\),然后让 \(a\) 是 \(k\) 的因子,\(b\) 是 \(k+1\) 的因子。因为 \(k\) 和 \(k+1\) 互质,所以 \(n\) 的相同质因子一定是给到 \(a,b\) 中同一个数。
由于前 \(13\) 个质数相乘就已经超过 \(10^{12}\),所以 \(n\) 不同质因子数量最多就是 \(12\)。可以先把 \(10^6\) 以内的质数筛出来,然后 \(2^k\) 枚举 \(n\) 的 \(k\) 个质因子分别扔到哪一边。
把 \(n\) 分解成 \(a\times b\) 后,我们需要找到 \(a,b\) 的倍数让他们的差为 \(1\)。也就是解 \(ax+by=1\) 的最小整数解。直接上 exgcd 即可。
时间复杂度 \(O(Q(m+2^k\log n))\),其中 \(m\) 是 \(10^6\) 以内质数数量 \(\leq 88000\),\(k\) 是不同质因子数量 \(\leq 12\)。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1000010;
const ll Inf=4e18;
int Q,m,prm[N];
bool v[N];
ll n,nn,ans;
vector<ll> d;
void findprm(int n)
{
for (int i=2;i<=n;i++)
{
if (!v[i]) prm[++m]=i;
for (int j=1;j<=m;j++)
{
if (i>n/prm[j]) break;
v[i*prm[j]]=1;
if (!(i%prm[j])) break;
}
}
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
if (!b) { x=1; y=0; return a; }
ll d=exgcd(b,a%b,x,y);
ll z=x; x=y; y=z-y*(a/b);
return d;
}
int main()
{
findprm(1000000);
scanf("%d",&Q);
while (Q--)
{
scanf("%lld",&n);
nn=n=2LL*n; ans=n-1;
d.clear();
for (int i=1;i<=m;i++)
if (!(nn%prm[i]))
{
ll res=1;
while (!(nn%prm[i])) nn/=prm[i],res*=prm[i];
d.push_back(res);
}
if (nn>1) d.push_back(nn);
int len=d.size(),lim=(1<<len);
for (int s=0;s<lim;s++)
{
ll v1=1,v2=1,x,y,_,__;
for (int i=0;i<len;i++)
if (s&(1<<i)) v1*=d[i];
else v2*=d[i];
ll g=exgcd(v1,v2,x,y);
g=exgcd(x,y,_,__); x/=g; y/=g;
if (x<0) ans=min(ans,-1LL*x*v1),ans=min(ans,y*v2);
if (y<0) ans=min(ans,-1LL*y*v2),ans=min(ans,x*v1);
}
cout<<ans<<"\n";
}
return 0;
}
原文地址:https://www.cnblogs.com/stoorz/p/15015850.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法