P1516 青蛙的约会和P2421 [NOI2002]荒岛野人
洛谷 P1516 青蛙的约会 、
算是手推了一次数论题,以前做的都是看题解,虽然这题很水而且还交了5次才过。。。
求解方程\(x+am\equiv y+an \pmod l\)中,\(a\)的最小整数解
\(0<x\neq y\leq 2\cdot 10^9,0<n,m\leq 2\cdot 10^9,0<l\leq 2.1\cdot 10^9\)
做一下变形:
\]
设\(w=x-y,r=n-m\),则
\]
此时,设\(\gcd(l,r)=gcd\),那么可以分两种情况
如果\(w\)是\(gcd\)的倍数,则原式可以写为:
\]
根据同余式的性质,可以将\(gcd\)化简掉,具体证明在这里
\]
此时,\(\gcd(r',l')=1\),那么可以求出\(r' \bmod l'\)的逆元
那么\(w'r'^{-1}\bmod l'\)即为答案
具体操作就是用 exgcd,求出一个\(qr+pl=\gcd(r,l)\),然后可以表示为\(qr'gcd+pl'gcd=gcd\)
\(gcd\)被约掉,就是\(qr'+pl'=1\),则\(q\)即为\(r'\bmod l'\)的逆元
还有一种情况\(w\)不是\(gcd\)的倍数,显然无解
再就是注意\(w,r\)会不会出现负数,如果有负数在取模的时候可能会出现一些玄学情况,要现在\(\bmod l\)下把他们变成正的
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline LL read(){
LL x=0,y=1;
char c=std::getchar();
while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
return y?x:-x;
}
LL exgcd(LL &x,LL &y,LL a,LL b){
if(!b) return x=1,y=0,a;
LL gcd=exgcd(x,y,b,a%b);
int xx=x;x=y;
y=xx-a/b*y;
return gcd;
}
int main(){
LL n,m,x,y,l;
x=read();y=read();m=read();n=read();l=read();
if(m==n) return std::puts("Impossible"),0;
LL r=n-m,w=x-y;
if(r<0) r=(r+((-r/l)+1)*l)%l;
if(w<0) w=(w+((-w/l)+1)*l)%l;
LL a,b;
int gcd=exgcd(a,b,r,l);
if(w%gcd) return std::puts("Impossible"),0;
l/=gcd;w/=gcd;
std::printf("%lld",(w*a%l+l)%l);
return 0;
}
洛谷 P2421 [NOI2002]荒岛野人,LOJ上也有
这题和上面那个几乎一样,代码复制过去改一改加个主函数就行
克里特岛以野人群居而著称。岛上有排列成环行的\(M\)个山洞。这些山洞顺时针编号为 \(1,2,\dots,M\)
岛上住着\(n\)个野人,一开始依次住在山洞 \(C_1,C_2,\dots,C_n\)中。以后每年,第 \(i\) 个野人会沿顺时针向前走 \(P_i\)个洞住下来。
每个野人\(i\)有一个寿命值 \(L_i\),即生存的年数。
奇怪的是,虽然野人有很多,但没有任何两个野人在有生之年处在同一个山洞中,使得小岛一直保持和平与宁静,这让科学家们很是惊奇。他们想知道,至少有多少个山洞,才能维持岛上的和平呢?数据保证有解,\(M\) 的值不大于\(10^6\)
这是真正的数据范围,洛谷上标的很乱:\(0<C_i,P_i\leq 100,1\leq N\leq 15,0\leq L_i\leq 10^6\)
把题意描述成数学语言,就是求一个最小的\(M\),使得对于任意的\(i\neq j,c_i+kp_i\equiv c_j+kp_j \pmod M\)无解,或解大于\(\min(L_i,L_j)\)
然后这个式子就和上面那个题一模一样了,就是记得判断解的大小就行
一开始想二分处理,然而发现并不满足可二分性,但保证\(M\leq 10^6\),很小,而且又保证有解,所以可以从\(\max c_i\)开始枚举\(M\),枚举到成立就行了
复杂度\(O(Mn^2\log C_i)\),超过\(10^9\)了,而且这还是02年的题,那时候恐怕测评机比现在也慢
不过肯定是跑不满,也不太可能会有什么毒瘤数据,估计是没有更优做法了
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#define reg register
#define EN std::puts("")
#define LL long long
inline int read(){
register int x=0;register int y=1;
register char c=std::getchar();
while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
return y?x:-x;
}
int exgcd(int &x,int &y,int a,int b){
if(!b) return x=1,y=0,a;
LL gcd=exgcd(x,y,b,a%b);
int xx=x;x=y;
y=xx-a/b*y;
return gcd;
}
inline int check(int m,int n,int x,int y,int l,int min){//calc am+x = an+y mod l
if(m==n) return 0;
LL r=n-m,w=x-y;
if(r<0) r=(r+((-r/l)+1)*l)%l;
if(w<0) w=(w+((-w/l)+1)*l)%l;
int a,b;
int gcd=exgcd(a,b,r,l);
if(w%gcd) return 0;
w/=gcd;l/=gcd;
if((w*a%l+l)%l>min) return 0;
return 1;
}
int c[19],p[19],l[19];
int main(){
int n=read(),maxc=0;
for(reg int i=1;i<=n;i++) c[i]=read(),p[i]=read(),l[i]=read(),maxc=std::max(maxc,c[i]);
for(reg int m=maxc;;m++){
for(reg int i=1;i<=n;i++)
for(reg int j=i+1;j<=n;j++)
if(check(p[i],p[j],c[i],c[j],m,std::min(l[i],l[j]))) goto FAIL;
return std::printf("%d",m),0;
FAIL:;
}
return 0;
}
P1516 青蛙的约会和P2421 [NOI2002]荒岛野人的更多相关文章
- bzoj1407 / P2421 [NOI2002]荒岛野人(exgcd)
P2421 [NOI2002]荒岛野人 洞穴数不超过1e6 ---> 枚举 判断每个野人两两之间是否发生冲突:exgcd 假设有$m$个洞穴,某两人(设为1,2)在$t$时刻发生冲突 那么我们可 ...
- 【题解】洛谷P2421[NOI2002]荒岛野人 (Exgcd)
洛谷P2421:https://www.luogu.org/problemnew/show/P2421 思路 从洞的最大编号开始增大枚举答案 对于每一个枚举的ans要满足Ci+k*Pi≡Cj+k*Pj ...
- 洛谷P2421 [NOI2002]荒岛野人(扩展欧几里得)
题目背景 原 A-B数对(增强版)参见P1102 题目描述 克里特岛以野人群居而著称.岛上有排列成环行的M个山洞.这些山洞顺时针编号为1,2,…,M.岛上住着N个野人,一开始依次住在山洞C1,C2,… ...
- Luogu P2421 [NOI2002]荒岛野人
最近上课时提到的一道扩欧水题.还是很可做的. 我们首先注意到,如果一个数\(s\)是符合要求的,那么那些比它大(or 小)的数不一定符合要求. 因此说,答案没有单调性,因此不能二分. 然后题目中也提到 ...
- P2421 [NOI2002]荒岛野人
传送门 答案不大于 $10^6$,考虑枚举答案 对于枚举的 ans,必须满足对于任意 i,j(i≠j) 都有 使式子$c_i+kp_i \equiv c_j+kp_j\ (mod\ ans)$成立的最 ...
- P2421 [NOI2002]荒岛野人 扩展欧几里得 枚举
Code: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; ...
- 洛谷 P2421 [NOI2002]荒岛野人
题目描述 又是一道扩欧的题. 要求一个最小的m使得 Ci+Pi*x≡Cj+Pj*x mod m(i!=j) 在x在第i个人和第j个人的有生之年无解. 也就是 (Pi-Pj)*x+m*y=Cj-Ci 在 ...
- P1516 青蛙的约会
P1516 青蛙的约会x+mt-p1L=y+nt-p2L(m-n)t+L(p2-p1)=y-x令p=p2-p1(m-n)t+Lp=y-x然后套扩欧就完事了 #include<iostream&g ...
- 洛谷 P1516 青蛙的约会 解题报告
P1516 青蛙的约会 题目描述 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件 ...
随机推荐
- python 函数简介
一.为什么要有函数? 不加区分地将所有功能的代码垒到一起,问题是: 代码的可读性差. 代码冗余 代码可扩展性差 如何解决? 函数即工具,事先准备工具的过程是定义函数,拿来就用指的是函数调用. 什么是函 ...
- 正则表达式 regex
正则表达式存在于String api下的matches方法 常用正常表达式: 字符 x 字符 x \\ 反斜线字符 字符类 [abc] a.b 或 c(简单类) [^abc] 任何字符,除了 a.b ...
- java消除 list重复值及交集,并集,差集
消除 list重复值 Java代码 public void removeDuplicate(List list) { HashSet h = new HashSet(list); list.clea ...
- intellij idea 设置用真机测试android
android自带的模拟器是不容置疑的慢,genymontion虽然快,但是觉得有点怪的感觉,哈哈,其实这些都不是重点. 之前是用myeclipse开发android的,虽然一直很想用eclipse来 ...
- (转) POJO和javabean的异同
参考:http://blog.csdn.net/lushuaiyin/article/details/7436318 一:什么是POJOPOJO的名称有多种,pure old java object ...
- python字节码,java字节码,十六进制相互转换
下面是互相转换的代码: 有想要了解更多关于python知识的请在下方评论或私信小编
- 将函数作为返回值的方法 - Python
有的时候,我们需要将函数作为返回值,以下为代码: def superfunc(): i = 0 def wrapper(): nonlocal i i +=1 return i return wrap ...
- Python 实用冷门知识整理
1.print 打印带有颜色的信息 大家知道 Python 中的信息打印函数 print,一般我们会使用它打印一些东西,作为一个简单调试. 但是你知道么,这个 Print 打印出来的字体颜色是可以设置 ...
- 立体匹配-----NCC视差匹配
目录 一.立体匹配算法 1.立体匹配算法分类 二.NCC 视差匹配方法 1.原理 2.NCC计算公式 3.算法流程 4.代码实现 5.不同场景运行 三.结论 四.遇到的问题及解决方法 一.立体 ...
- js上传文件前判断获取文件大小并且加以判断
描述:要求浏览器单个上传文件大小不超过10M. 解决方案: var fileSize = $("#fileId")[0].files[0].size/(1024*1024);if( ...