前言

我们熟知的中国剩余定理,在使用条件上其实是很苛刻的,要求模线性方程组\(x\equiv c(\mod m)\)的模数两两互质。

于是就有了扩展中国剩余定理,其实现方法大概是通过扩展欧几里德把两个同余方程合并,具体会在下面提到。

但是,使用仍有限制,那就是\(x\)的系数必须为\(1\)。

没关系,把它再扩展一下

题目及实现

洛谷题目传送门

题意分析

显然,如果我们能干掉所有龙,那么每一次使用的剑的攻击力是已知的,设为\(k\)。那么对于每一条龙,攻击次数\(x\)必须满足\(kx\equiv a(\mod p)\);当然别忘记要先把生命值降到非正数,也就是说还要满足\(kx\geq a\)即\(x\geq\lceil\frac a k\rceil\)。

可以看出不能直接用扩展中国剩余定理,但不妨碍先介绍一下它。

扩展中国剩余定理

如果有一个模线性方程组,每个形如\(x\equiv c(\mod m)\),而且不保证\(m\)两两互质,就用不了中国剩余定理了。

扩展中国剩余定理是这样做的。

我们先把问题简化到一个方程组只有两个方程的情况,形如

\[\begin{cases}x\equiv c_1(\mod m_1)\\x\equiv c_2(\mod m_2)\end{cases}
\]

把它写成不定方程的形式

\[\begin{cases}x=c_1+m_1x_1\\x=c_2+m_2x_2\end{cases}
\]

这样就可以合并了,解一下\(x_1\),所以\(x_2\)可变号

\[c_1+m_1x_1=c_2+m_2x_2\\m_1x_1+m_2x_2=c_1-c_2
\]

发现变成了一个二元一次不定方程的样子,设\(g=gcd(m_1,m_2)\),用扩展欧几里德求\(m_1x_1+m_2x_2=g\)中\(x_1\)的一个解\(x'\),于是用\(\frac{c_1-c_2}gx'+\frac{m_2}gt(t\in\mathbb Z)\)可以表示\(x_1\)的解集(关于一般二元一次不定方程的解法和解的周期性证明可以看看蒟蒻之前写的一篇题解

把解集带回\(x=c_1+m_1x_1\)得到

\[x=c_1+\frac{m_1(c_1-c_2)}gx'+\frac{m_1m_2}gt
\]

\[x\equiv c_1+\frac{m_1(c_1-c_2)}gx'(\mod {\frac{m_1m_2}g})
\]

这样,我们设初始方程为\(x\equiv 0(\mod1)\),每次合并两个方程得到新的方程。当然中途如果有一次出现\(\frac{c_1-c_2}g\)不为整数则整个方程组无解。

再扩展

那么模线性方程组,每个形如\(kx\equiv a(\mod p)\)该怎么解好呢?

还是要合并方程。仍然设一个总方程\(x\equiv c(\mod m)\),将它与当前方程合并。

下面是同步赛上手推的式子,请直接跳过这一段,因为式子是错的,只有45分。说不定有些Dalao和我的想法一样?

直接合并

\[\begin{cases}x=c+mx_0\\kx+py_0=a\end{cases}\\k(mx_0+c)+py_0=a\\kmx_0+py_0=a-kc
\]

设\(g=gcd(km,p)\),解不定方程得到一个解\(x'\),有

\[x_0=\frac{a-kc}gx'+\frac p gt\\x=c+\frac{m(a-kc)}gx'+\frac{mp}gt
\]

\[x=c+\frac{m(a-kc)}gx'(\mod\frac{mp}g)
\]

为什么不能直接合并呢?因为连当前\(kx\equiv a(\mod p)\)能不能解都没有考虑。

所以正确的方法应该是先解当前方程\(kx+py=a\)。

设\(g=gcd(k,p)\),解\(x'\),得\(x=\frac a gx'+\frac p gt\)即\(x\equiv\frac a gx'(\mod\frac p g)\)

方程里\(x\)的系数被去掉了!可以从求逆元的角度来理解这一个过程。

当然,会有一些特殊情况。如果\(p\mid k\)且\(p\mid a\),方程恒成立,我们不把它与总方程合并。如果\(p\mid k\)且\(p\nmid a\),显然无解。

最后就是用扩展中国剩余定理合并啦。

具体实现

确定每次攻击使用的剑,直接用multiset解决,二分找到满足要求的剑(比较舒服的是upper_bound找第一个比要求大的剑,如果等于begin-iterator的话就说明没有不大于要求值的,直接选它,否则--iterator就是满足要求的),把它删掉,再加入当前奖励的剑。注意删的时候删的是iterator而不是数字。

再次提醒要注意\(x\geq\lceil\frac a k\rceil\)。可以求出\(\max\{\lceil\frac a k\rceil\}\),如果最后总方程的\(c\)小于它,则要补至满足条件的最小值,用式子写一下大概是\(c+m\lceil\frac{\max-c}{m} \rceil\)(可以理解成,现在c和max还有差距,但是为了保证c模m的值不变,所以一次次给c加上m直到大于等于max)。

注意数据范围,会爆longlong的地方用快速乘。注意处理负数。

多组数据,注意清空和初始化。

#include<cstdio>
#include<set>
#define RG register
#define R RG LL
#define GC c=getchar()
using namespace std;
typedef long long LL;
const int N=1e5+9;
LL a[N],p[N],b[N],X,Y,G;
multiset<LL>s;
inline LL in(){
RG char GC;
while(c<'-')GC;
R x=c&15;GC;
while(c>'-')x*=10,x+=c&15,GC;
return x;
}
void exgcd(R a,R b){
if(!b){X=1;Y=0;G=a;return;}
exgcd(b,a%b);
(Y^=X^=Y^=X)-=a/b*X;
}
inline LL mul(R b,R k,R m){//快速乘
R a=0;
for(;k;k>>=1,b=(b<<1)%m)
if(k&1)a=(a+b)%m;
return a;
}
int main(){
freopen("dragon.in","r",stdin);
freopen("dragon.out","w",stdout);
R T=in(),n,m,i,c,k,mx;
RG multiset<LL>::iterator it;
E:while(T--){
n=in();m=in();
for(i=1;i<=n;++i)a[i]=in();
for(i=1;i<=n;++i)p[i]=in();
for(i=1;i<=n;++i)b[i]=in();
s.clear();//注意清空
for(i=1;i<=m;++i)s.insert(in());
mx=c=0;m=1;//初始总方程
for(i=1;i<=n;++i){
it=s.upper_bound(a[i]);//谨慎选择lower_bound和upper_bound
if(it!=s.begin())--it;
k=*it;s.erase(it);s.insert(b[i]);//小心手一滑erase(*it)(居然还有90分)
mx=max(mx,(a[i]-1)/k+1);//更新限制
k%=p[i];a[i]%=p[i];//开始解方程,去掉系数
if(!k&&a[i]){puts("-1");goto E;}
if(!k&&!a[i])continue;//这两个要特判
exgcd(k,p[i]);
if(a[i]%G){puts("-1");goto E;}
p[i]/=G;
a[i]=mul(a[i]/G,(X%p[i]+p[i])%p[i],p[i]);
exgcd(m,p[i]);//开始合并,X和a-c都可能是负数
if((a[i]-c)%G){puts("-1");goto E;}
m=m/G*p[i];
c=(c+mul(mul(m/p[i],((a[i]-c)%m+m)%m,m),(X%m+m)%m,m))%m;
}
printf("%lld\n",c>=mx?c:c+m*((mx-c-1)/m+1));//满足限制
}
return 0;
}

(伪)再扩展中国剩余定理(洛谷P4774 [NOI2018]屠龙勇士)(中国剩余定理,扩展欧几里德,multiset)的更多相关文章

  1. [洛谷P4774] [NOI2018]屠龙勇士

    洛谷题目链接:[NOI2018]屠龙勇士 因为markdown复制过来有点炸格式,所以看题目请戳上面. 题解: 因为杀死一条龙的条件是在攻击\(x\)次,龙恢复\(y\)次血量\((y\in N^{* ...

  2. 洛谷P4774 [NOI2018]屠龙勇士 [扩欧,中国剩余定理]

    传送门 思路 首先可以发现打每条龙的攻击值显然是可以提前算出来的,拿multiset模拟一下即可. 一般情况 可以搞出这么一些式子: \[ atk_i\times x=a_i(\text{mod}\ ...

  3. 洛谷 P4774 [NOI2018] 屠龙勇士

    链接:P4774 前言: 交了18遍最后发现是多组数据没清空/ll 题意: 其实就是个扩中. 分析过程: 首先发现根据题目描述的选择剑的方式,每条龙对应的剑都是固定的,有查询前驱,后继(在该数不存在前 ...

  4. P4774 [NOI2018]屠龙勇士

    P4774 [NOI2018]屠龙勇士 先平衡树跑出打每条龙的atk t[] 然后每条龙有\(xt \equiv a[i](\text{mod }p[i])\) 就是\(xt+kp[i]=a[i]\) ...

  5. luogu P4774 [NOI2018]屠龙勇士

    传送门 这题真的是送温暖啊qwq,而且最重要的是yyb巨佬在Day2前几天正好学了crt,还写了博客 然而我都没仔细看,结果我就同步赛打铁了QAQ 我们可以先根据题意,使用set维护,求出每次的攻击力 ...

  6. 【洛谷 P4777】 【模板】扩展中国剩余定理(EXCRT)

    注意一下:: 题目是 \[x≡b_i\pmod {a_i}\] 我总是习惯性的把a和b交换位置,调了好久没调出来,\(qwq\). 本题解是按照 \[x≡a_i\pmod {b_i}\] 讲述的,请注 ...

  7. 扩展中国剩余定理学习笔记+模板(洛谷P4777)

    题目链接: 洛谷 题目大意:求同余方程组 $x\equiv b_i(mod\ a_i)$ 的最小正整数解. $1\leq n\leq 10^5,1\leq a_i\leq 10^{12},0\leq ...

  8. 中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结

    中国剩余定理(CRT) & 扩展中国剩余定理(ExCRT)总结 标签:数学方法--数论 阅读体验:https://zybuluo.com/Junlier/note/1300035 前置浅讲 前 ...

  9. 中国剩余定理(crt)和扩展中国剩余定理(excrt)

    数论守门员二号 =.= 中国剩余定理: 1.一次同余方程组: 一次同余方程组是指形如x≡ai(mod mi) (i=1,2,…,k)的同余方程构成的组 中国剩余定理的主要用途是解一次同余方程组,其中m ...

随机推荐

  1. flask-script&flask-migrate使用

    一.简介 Flask-script扩展提供向Flask插入外部脚本的功能,包括运行一个开发用的服务器,一个定制的Python shell.设置数据库的脚本.cronjobs及其他运行在web应用之外的 ...

  2. webpackt入门1:webpack介绍&webpack安装&使用webpack打包

    本篇博客不是原创,简书的zhangwang写的,原文太长,我这里只是提取了一部分. 原文地址:入门webpack,看这篇就够了 一.Webpack解决了什么问题 问题1.JavaScript这个脚本化 ...

  3. 大数据之Flume

    什么是Flume ApacheFlume是一个分布式的.可靠的.可用的系统,用于高效地收集.聚合和将大量来自不同来源的日志数据移动到一个集中的数据存储区. 系统要求 1. JDK 1.8 或以上版本 ...

  4. 浅谈nornalize.css(含源码)

    Normalize.css是一种CSS reset的替代方案.经过@necolas和@jon_neal花了几百个小时来努力研究不同浏览器的默认样式的差异,这个项目终于变成了现在这样. 我们创造norm ...

  5. monkey测试基础

    一.环境配置 Java JDK和android SDK 二.基本命令 *安卓手机链接电脑,打开手机的开发者模式,允许usb调试 adb:检查adb是否安装成功 adb devices:查看连接的设备 ...

  6. Codeforces Round #505 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)-C. Plasticine zebra

    问了学长,感觉还是很迷啊,不过懂了个大概,这个翻转操作,实质不就是在序列后面加上前面部分比如 bw | wwbwwbw  操作过后 wbwbwwbww 而 bw | wwbwwbwbw 这样我们就知道 ...

  7. 【Beta阶段】第七次Scrum Meeting!

    每日任务内容: 本次会议为第七次Scrum Meeting会议~ 由于本次会议项目经理召开时间为10:00,在宿舍召开,召开时长约20分钟. 队员 昨日完成任务 明日要完成任务 刘乾 #177(未完成 ...

  8. 百度AI--自然语言处理之Java开发

    参数: public class APIConstants { //设置APPID/AK/SK public static final String APP_ID = "108***&quo ...

  9. Delphi的idhttp报IOHandler value is not valid错误的原因[转]

    出现这种问题的原因是由于访问的 URL地址为https或存在其跳转地址为https. 首先单纯使用idhttp是只能访问http,而https则需要搭配IdSSLIOHandlerSocketOpen ...

  10. ECSHOP后台登陆后一段时间不操作就超时的解决方法

    ECSHOP后台登陆后一段时间不操作就超时的解决方法 ECSHOP教程/ ecshop教程网(www.ecshop119.com) 2012-05-27   客户生意比较好,因此比较忙,常常不在电脑前 ...