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 青蛙的约会 题目描述 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件 ...
随机推荐
- MySQL学习之路5-数据表的常用操作
排序 :order by desc select * from <tablename> order by <字段名> desc:order by默认升序 desc 降序 分组 ...
- TP3快速入门
一.查询 D方法实例化模型类的时候通常是实例化某个具体的模型类,如果你仅仅是对数据表进行基本的CURD操作的话,使用M方法实例化的话,由于不需要加载具体的模型类,所以性能会更高. $map = arr ...
- Python Requests-学习笔记(11)-请求与响应对象
任何时候调用requests.*()你都在做两件主要的事情.其一,你在构建一个 Request 对象, 该对象将被发送到某个服务器请求或查询一些资源.其二,一旦 requests 得到一个从 服务器返 ...
- PostgreSQL中RECURSIVE递归查询使用总结
RECURSIVE 前言 CTE or WITH 在WITH中使用数据修改语句 WITH使用注意事项 RECURSIVE 递归查询的过程 拆解下执行的过程 1.执行非递归部分 2.执行递归部分,如果是 ...
- csdn的垃圾体验
微信扫码登录网页csdn,每次扫码都是csdn有关的不同的公众号,必须关注才可以登录,为了推广公众号真是简直了 无法修改id 注销也需要扫码,这次是必须下载csdn的app才能注销,我真是服了,我都要 ...
- ValidForm.js的使用注意点
dataType的值不能为"", 否则会导致错误发生:Uncaught TypeError: Cannot read property '0' of null,http请求可以发送 ...
- 4. js
1.) ~ 操作符 console.log(~-2) // 1 console.log(~-1) // 0 console.log(~0) // -1 console.log(~1) // ...
- mysql 更改默认字符集
mysql 默认字符集概述 首先,MySQL的字符集问题主要是两个概念: haracter Sets Collations 前者是字符内容及编码,后者是对前者进行比较操作的一些规则.这两个参数集可以在 ...
- cli命令速查
在文件的指定行(n)插入指定内容: sed -i "niecho "haha"" a 执行后,在a文件的第n行插入echo "haha" 多 ...
- pytorch 中序列化容器nn.Sequential
按下图顺序搭建以及执行