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 ...
随机推荐
- 微软Ignite2018——微软宣布新的学习平台:Microsoft Learn
Ignite 2018 首日感受 头一次参加美国的微软 Ignite 大会,确实规模比国内的大不少.23日是 MVP & RD 的 Pre Day(MVP即Most Valuable Prof ...
- Linux stress 命令
stress 命令主要用来模拟系统负载较高时的场景,本文介绍其基本用法.文中 demo 的演示环境为 ubuntu 18.04. 基本语法 语法格式:stress <options> 常用 ...
- Leetcode -- 394. Decode String
Given an encoded string, return it's decoded string. The encoding rule is: k[encoded_string], where ...
- Python学习第十五篇——类继承和类实例化
学习Python类时,我们明白了类的本质,以及所谓的面向对象编程思想强调的对事物本身的属性,我们对某一类事物进行描述——采用了很多方法,这些方法描述了类的属性(比如猫科动物的眼睛,四肢,是否哺乳类等等 ...
- OSS网页上传和断点续传(STSToken篇)
云账号AccessKey拥有所有API访问权限,在客户端不要直接使用,会泄露ak信息,造成安全问题.所以使用STS方式(临时账号权限)给客户端授权. C#版获取STSToken 一.下载阿里SDK(a ...
- c语言之字符串和格式化输入输出
字符串和格式化输入输出 #include<stdio.h> #include<string.h> #define DENSITY 62.4 int main(void) { f ...
- Socket编程,SocketServer模块
一.SocketServer的几种类型 面向远程: TCP 协议链接:socketserver.TCPServer(server_address, RequestHandlerClass, bind_ ...
- 几个jdbc小技巧
版本:jdk:1.6mysql-connector-5.0.8 1.如何用jdbc判断某个基本表是否存在 一种比较“笨”的方法: try{ stmt.executeQuery( ...
- 【转】shell之for、while、until循环
一.简介 Shell编程中循环命令用于特定条件下决定某些语句重复执行的控制方式,有三种常用的循环语句:for.while和until.while循环和for循环属于“当型循环”,而unti ...
- 学习WebSocket
初识WebSocket: index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8 ...