LOJ2721 [NOI2018] 屠龙勇士 【扩展中国剩余定理】
好久没写了,写一篇凑个数。
题目分析:
这题不难想,讲一下中国剩余定理怎么扩展。
考虑$$\left\{\begin{matrix}x \equiv a\pmod{b}\\ x \equiv c\pmod{d}\end{matrix}\right.$$
不难发现需要满足$gcd(b,d)|(c-a)$才有解。
结合后的模数一定是$lcm(b,d)$。然后扩展gcd合并就行了。
中间过程会超过$10^18$,需要快速乘。
代码:
#include<bits/stdc++.h>
using namespace std; const int maxn = ; int n,m;
long long a[maxn],p[maxn],LP[maxn],d[maxn]; multiset<long long,greater<long long> > s; long long cut[maxn],minn;
long long st[maxn],f[maxn]; void init(){
s.clear();memset(st,,sizeof(st)); memset(f,,sizeof(f));
for(int i=;i<=m;i++) s.insert(d[i]);
for(int i=;i<=n;i++){
set<long long>::iterator it = s.lower_bound(a[i]);
if(it == s.end())it--; cut[i] = (*it);
s.erase(it); s.insert(LP[i]);
}
minn = ;
for(int i=;i<=n;i++) minn = max(minn,(long long)ceil((double)a[i]/cut[i]));
} long long exgcd(long long alpha,long long beta,long long &x,long long &y){
if(beta == ){x = ; y = ; return alpha;}
else{
long long res = exgcd(beta,alpha%beta,y,x);
y-=x*(alpha/beta);
return res;
}
} void read(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++) scanf("%lld",&a[i]);
for(int i=;i<=n;i++) scanf("%lld",&p[i]);
for(int i=;i<=n;i++) scanf("%lld",&LP[i]);
for(int i=;i<=m;i++) scanf("%lld",&d[i]);
} long long multi(long long alpha,long long beta,long long mod){
long long dt,bit = ,ans = ;
alpha %= mod; beta %= mod;
alpha += mod; beta += mod;
alpha %= mod; beta %= mod;
dt = alpha;
while(bit <= beta){
if(bit & beta){ans += dt; if(ans >= mod) ans -= mod;}
bit<<=;dt = (dt+dt); if(dt >= mod) dt -= mod;
}
return ans;
} int cntt = ;
void work(){
for(int i=;i<=n;i++){
long long hd = exgcd(cut[i],p[i],st[i],f[i]);
if(a[i] % hd != ){puts("-1");return;}
f[i] = p[i]/hd; st[i] %= f[i]; if(st[i] < ) st[i] += f[i];
st[i] = multi(st[i],a[i]/hd,f[i]); st[i] %= f[i];
}
for(int i=;i<=n;i++){
long long im = exgcd(f[i],f[i-],f[],f[]);
if((st[i]-st[i-])%im){
puts("-1");return;
}
long long um = f[i]/im*f[i-];
long long tf=; exgcd(f[i-],f[i],tf,f[]);
tf =multi(tf,(st[i]-st[i-])/im,um);
tf += (-tf/f[i])*f[i]; tf += f[i];
tf = (st[i-]+multi(tf,f[i-],um))%um;
if(tf < ) tf += um;
f[i] = um; st[i] = tf;
}
if(st[n] < minn){
st[n] += (minn-st[n])/f[n]*f[n];
}
printf("%lld\n",st[n]);
//fast multi
} int main(){
int Tmp; scanf("%d",&Tmp);
while(Tmp--){
cntt++;
read();
init();
work();
}
return ;
}
LOJ2721 [NOI2018] 屠龙勇士 【扩展中国剩余定理】的更多相关文章
- LOJ.2721.[NOI2018]屠龙勇士(扩展CRT 扩展欧几里得)
题目链接 LOJ 洛谷 rank前3无压力(话说rank1特判打表有意思么) \(x*atk[i] - y*p[i] = hp[i]\) 对于每条龙可以求一个满足条件的\(x_0\),然后得到其通解\ ...
- 洛谷P4774 BZOJ5418 LOJ2721 [NOI2018]屠龙勇士(扩展中国剩余定理)
题目链接: 洛谷 BZOJ LOJ 题目大意:这么长的题面,就饶了我吧emmm 这题第一眼看上去没法列出同余方程组.为什么?好像不知道用哪把剑杀哪条龙…… 仔细一看,要按顺序杀龙,所以获得的剑出现的顺 ...
- 扩展中国剩余定理学习笔记+模板(洛谷P4777)
题目链接: 洛谷 题目大意:求同余方程组 $x\equiv b_i(mod\ a_i)$ 的最小正整数解. $1\leq n\leq 10^5,1\leq a_i\leq 10^{12},0\leq ...
- (伪)再扩展中国剩余定理(洛谷P4774 [NOI2018]屠龙勇士)(中国剩余定理,扩展欧几里德,multiset)
前言 我们熟知的中国剩余定理,在使用条件上其实是很苛刻的,要求模线性方程组\(x\equiv c(\mod m)\)的模数两两互质. 于是就有了扩展中国剩余定理,其实现方法大概是通过扩展欧几里德把两个 ...
- BZOJ5418[Noi2018]屠龙勇士——exgcd+扩展CRT+set
题目链接: [Noi2018]屠龙勇士 题目大意:有$n$条龙和初始$m$个武器,每个武器有一个攻击力$t_{i}$,每条龙有一个初始血量$a_{i}$和一个回复值$p_{i}$(即只要血量为负数就一 ...
- [洛谷P4774] [NOI2018]屠龙勇士
洛谷题目链接:[NOI2018]屠龙勇士 因为markdown复制过来有点炸格式,所以看题目请戳上面. 题解: 因为杀死一条龙的条件是在攻击\(x\)次,龙恢复\(y\)次血量\((y\in N^{* ...
- 扩展中国剩余定理 (exCRT) 的证明与练习
原文链接https://www.cnblogs.com/zhouzhendong/p/exCRT.html 扩展中国剩余定理 (exCRT) 的证明与练习 问题模型 给定同余方程组 $$\begin{ ...
- P4777 【模板】扩展中国剩余定理(EXCRT)/ poj2891 Strange Way to Express Integers
P4777 [模板]扩展中国剩余定理(EXCRT) excrt模板 我们知道,crt无法处理模数不两两互质的情况 然鹅excrt可以 设当前解到第 i 个方程 设$M=\prod_{j=1}^{i-1 ...
- P4777 【模板】扩展中国剩余定理(EXCRT)
思路 中国剩余定理解决的是这样的问题 求x满足 \[ \begin{matrix}x \equiv a_1(mod\ m_1)\\x\equiv a_2(mod\ m_2)\\ \dots\\x\eq ...
随机推荐
- 剑指offer 第十二天
58.对称的二叉树 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. /* public class TreeNode { int val ...
- ASP.NET MVC5+EF6+EasyUI 仓库管理系统
简介 此系统是在框架基础上叠加的仓库系统功能,同样是开源的,可以用于简单的仓库管理,您也可以在此基础上继续开发与完善! 仓库的框架功能会随着框架的升级而同样升级,仓库管理售价1666,已经购买过框架的 ...
- CodeForces - 1051D-简单DP
这个题叫问给一个2*N的方块,你可以在每一个上填任意黑或者白两种,假设颜色相同的并且有公共边的就被认为是一块,问组成K块有多少种方案. 这题开始感觉无从下手,像组合数学又不像的,其实这个题的关键在于, ...
- Array Division CodeForces - 808D (构造+实现)
Vasya has an array a consisting of positive integer numbers. Vasya wants to divide this array into t ...
- (poj 2253) Frogger 最短路上的最大路段
题目链接:http://poj.org/problem?id=2253 Description Freddy Frog is sitting on a stone in the middle of a ...
- Python2和Python3中urllib库中urlencode的使用注意事项
前言 在Python中,我们通常使用urllib中的urlencode方法将字典编码,用于提交数据给url等操作,但是在Python2和Python3中urllib模块中所提供的urlencode的包 ...
- 实现数据结构与算法需要掌握的C语言
我使用C语言并不频繁,一般都是用来实现数据结构与算法,因为面向过程的编程方式容易理解算法的原理,但是呢,如果很长时间没写算法,那么就意味着C语言的某些语法就生疏了,但是总有那么一些,在写算法的时候,特 ...
- Eclipse Todo Tasks 任务试图
java - Find TODO tags in Eclipse - Stack Overflowhttps://stackoverflow.com/questions/16903046/find-t ...
- storm问题汇总
1.删除了本地topology导致无法启动nimbus 删除storm的自定义的库中的数据 删除zookeeper中配置的dataDir中的数据 重启服务即可
- ES6学习之let
块级作用域 ; i < ; i++){} console.log(i); ; j < ; j++){} console.log(j); //"ReferenceError: j ...