NOI2018Day2T1 屠龙勇士 set 扩展欧几里德 中国剩余定理
原文链接https://www.cnblogs.com/zhouzhendong/p/NOI2018Day2T1.html
题目传送门 - 洛谷P4774
题意


题解
首先我们仔细看一看样例可以发现如果一回合打不过巨龙就输了。
所以每一回合都要赢。所以每一次选择的宝剑都是可以提前预知的。
我们用个 set 来支持快速插入和 upper_bound ,可以在 $O((n+m)\log m)$ 的时间复杂度内处理得到每一把宝剑要处理的巨龙。
我们考虑化简一下原题的意思:
令 $v_i$ 为攻击第 $i$ 只龙的宝剑的攻击力。
则对于最终答案 $x$ 必然满足:
$$\forall i\in \{1,2,\cdots,n\}$$
$$a_i\leq x\times v_i$$
$$a_i\equiv x\times v_i\pmod {p_i}$$
我们先考虑第二个条件。
$$a_i\equiv x\times v_i\pmod {p_i}\Longrightarrow x\equiv \cfrac{a_i}{v_i}\pmod {p_i}$$
于是我们需要求出 $(v_i)^{-1} \pmod {p_i}$ 。
但是 $v_i$ 的逆元在对 $p_i$ 取模意义下不一定存在,不存在的条件是 $\gcd(v_i,p_i)>1$ 。这个求逆元一般方法自己百度。
但是即使不存在,也有可能使得 $x\times v_i\equiv a_i$ 。
我们来看一看原式的本质:
$$a_i=x\times v_i + k\times p_i$$
令 $g=\gcd(a_i,v_i,p_i)$ ,上式中的 $a_i,v_i,p_i$ 都除以 $g$ ,上式依旧成立。
接下来,上述 $a_i,v_i,p_i$ 的值都更新成他们除以 $g$ 的值。
此时,如果 $g2=\gcd(v_i,p_i)>1$ ,那么由于 $\gcd(g2,a_i)=1$ ,所以有 $x\times v_i + k\times p_i = M\times g2 \not \equiv a_i \pmod {g2 \times (p_i÷g2)}$ ,其中 $M=(x\times v_i + k\times p_i)÷g2$ 。
那么显然无解了。
如果 $g2=1$ ,那么显然有解。
于是我们依照上述做法,可以判除掉一部分无解的情况,并得到关于 $x$ 的一次同余方程组。
令 $x_i=a_i\times (v_i)^{-1}\pmod {p_i}$ ,则:
$$\begin{cases}x&\equiv&x_1&\pmod {p_1}\\x&\equiv&x_2&\pmod {p_2}\\ &&\vdots\\x&\equiv&x_n&\pmod {p_n}\end{cases}$$
这个东西直接中国剩余定理合并一下(可能会无解)就可以得到 $x\equiv W \pmod P$ 这样的一般式子了。由于本题数据范围比较大,我用了快速乘来防止炸 $long \ long $ 。
得到 $x$ 的一般同余式子之后,我们再去看看之前的第一个条件。
$\forall i\in\{1,2,\cdots,n\}, \ \ \ a_i\leq x$
由于 $x=kP + W$ ,所以我们可以将 $x$ 代入上面的式子中,并根据所有的式子求出 $k$ 的取值范围。于是就可以得到 $x$ 的最小值了!
时间复杂度 $O(n\log n)$ 。
期望得分 : 100
UPD(2018-07-20 22:16): 洛谷测试 :100
UPD(2018-07-21): LOJ测试 :100
UPD(2018-07-22): 评测鸭测试: 100
UPD(2018-07-24): UOJ测试 : 100
UPD(2018-xxxxx): xxx测试:100
实际得分 : 75 (该分数为推测结果( Day2 少了 25 分大概只有可能是这里了))
吐槽啊!CCF 老爷机跑的也太慢了吧??是不是没有开 O2 啊?
代码
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <vector>
#include <set>
#include <queue>
using namespace std;
typedef long long LL;
bool isd(char ch){
return '0'<=ch&&ch<='9';
}
LL read(){
LL x=0;
char ch=getchar();
while (!isd(ch))
ch=getchar();
while (isd(ch))
x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x;
}
const int N=100005;
int T,n,m;
LL a[N],p[N],h[N],v[N],x[N];
multiset <LL> S;
LL ex_gcd(LL a,LL b,LL &x,LL &y){
if (!b){
x=1,y=0;
return a;
}
LL res=ex_gcd(b,a%b,y,x);
y-=x*(a/b);
return res;
}
LL gcd(LL a,LL b){
return b?gcd(b,a%b):a;
}
LL inv(LL v,LL p){
LL x,y,g=ex_gcd(v,p,x,y);
if (g>1)
return -1;
return (x+p)%p;
}
LL Mul(LL a,LL b,LL p){
a=(a%p+p)%p;
b=(b%p+p)%p;
LL ans=0;
for (;a;a>>=1,b=(b<<1)%p)
if (a&1LL)
ans=(ans+b)%p;
return ans;
}
bool CRT(LL w1,LL p1,LL w2,LL p2,LL &w,LL &p){
LL x,y,z=w2-w1,g=ex_gcd(p1,p2,x,y);
if (z%g)
return 0;
LL t=z/g;
x=Mul(x,t,p2/g);
p=p1/g*p2;
w=((w1+Mul(x,p1,p))%p+p)%p;
return 1;
}
LL Solve(){
n=read(),m=read();
for (int i=1;i<=n;i++)
a[i]=read();
for (int i=1;i<=n;i++)
p[i]=read();
for (int i=1;i<=n;i++)
h[i]=read();
S.clear();
while (m--)
S.insert(read());
for (int i=1;i<=n;i++){
multiset <LL> :: iterator p=S.begin();
if ((*p)<a[i])
p=--S.upper_bound(a[i]);
v[i]=*p,S.erase(p);
S.insert(h[i]);
}
for (int i=1;i<=n;i++){
LL g=gcd(a[i],gcd(v[i],p[i]));
v[i]/=g,p[i]/=g,a[i]/=g;
LL Inv=inv(v[i],p[i]);
if (Inv<0)
return -1LL;
x[i]=Mul(a[i],Inv,p[i]);
}
LL W=x[1],P=p[1];
for (int i=2;i<=n;i++)
if (!CRT(W,P,x[i],p[i],W,P))
return -1LL;
// x = W (mod P)
for (int i=1;i<=n;i++){
LL val=(a[i]+v[i]-1)/v[i];
if (val<=W)
continue;
LL k=(val-W+P-1)/P;
W+=k*P;
}
return W;
}
int main(){
freopen("dragon.in","r",stdin);
freopen("dragon.out","w",stdout);
scanf("%d",&T);
while (T--)
printf("%lld\n",Solve());
fclose(stdin);fclose(stdout);
return 0;
}
NOI2018Day2T1 屠龙勇士 set 扩展欧几里德 中国剩余定理的更多相关文章
- POJ2891 Strange Way to Express Integers 扩展欧几里德 中国剩余定理
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ2891 题意概括 给出k个同余方程组:x mod ai = ri.求x的最小正值.如果不存在这样的x, ...
- (伪)再扩展中国剩余定理(洛谷P4774 [NOI2018]屠龙勇士)(中国剩余定理,扩展欧几里德,multiset)
前言 我们熟知的中国剩余定理,在使用条件上其实是很苛刻的,要求模线性方程组\(x\equiv c(\mod m)\)的模数两两互质. 于是就有了扩展中国剩余定理,其实现方法大概是通过扩展欧几里德把两个 ...
- 洛谷P3868 [TJOI2009]猜数字(中国剩余定理,扩展欧几里德)
洛谷题目传送门 90分WA第二个点的看过来! 简要介绍一下中国剩余定理 中国剩余定理,就是用来求解这样的问题: 假定以下出现数都是自然数,对于一个线性同余方程组(其中\(\forall i,j\in[ ...
- NOI 2018 屠龙勇士 (拓展中国剩余定理excrt+拓展欧几里得exgcd)
题目大意:略 真是一波三折的一道国赛题,先学了中国剩余定理,勉强看懂了模板然后写的这道题 把取出的宝剑攻击力设为T,可得Ti*x=ai(mod pi),这显然是ax=c(mod b)的形式 这部分用e ...
- gcd,扩展欧几里得,中国剩余定理
1.gcd: int gcd(int a,int b){ ?a:gcd(b,a%b); } 2.中国剩余定理: 题目:学生A依次给n个整数a[],学生B相应给n个正整数m[]且两两互素,老师提出问题: ...
- [洛谷P4777] [模板] 扩展中国剩余定理
扩展中国剩余定理,EXCRT. 题目传送门 重温一下中国剩余定理. 中国剩余定理常被用来解线性同余方程组: x≡a[1] (mod m[1]) x≡a[2] (mod m[2]) ...... x≡a ...
- POJ 1006 中国剩余定理
#include <cstdio> int main() { // freopen("in.txt","r",stdin); ; while(sca ...
- [TCO 2012 Round 3A Level3] CowsMooing (数论,中国剩余定理,同余方程)
题目:http://community.topcoder.com/stat?c=problem_statement&pm=12083 这道题还是挺耐想的(至少对我来说是这样).开始时我只会60 ...
- 洛谷P2480 [SDOI2010]古代猪文(费马小定理,卢卡斯定理,中国剩余定理,线性筛)
洛谷题目传送门 蒟蒻惊叹于一道小小的数论题竟能涉及这么多知识点!不过,掌握了这些知识点,拿下这道题也并非难事. 题意一行就能写下来: 给定\(N,G\),求\(G^{\sum \limits _{d| ...
随机推荐
- js用replaceAll全部替换的方法
1 前言 js中字符串整体替换,只有自带的replace,并没有replaceAll,如果我们需要把字符串中的字符统一替换,可以用正则表达式,由于经常使用就在String直接加个原生方法,方便调用. ...
- CSS 重置默认样式
1. 概述 1.1 说明 css重置样式主要是为了让各个浏览器的CSS样式有一个统一的基准,使HTML元素样式在跨浏览器时有一致性的效果. 备注:浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的 ...
- 瑞联科技:Pwp3框架 调用存储过程返还数据集合 到前端界面展示
一:代码结构: 1:Js 代码结构 2:Java 代码结构 二:前端界面展示效果 为了数据安全性:界面数据做了处理 三:全端代码展示 1:main.vop <html> <head& ...
- <<人月神话>>阅读体会(一)
第一次听说人月神话还是在大一上学期的导论课那会儿,那会儿好像就已经确定了自己要学软件,于是就去问王建民老师能不能给我推荐几本软件工程方面的书,我想要提前自己学学,以为老师会给我推荐一些某种语言类的学习 ...
- 进程与程序 并行 并发 串行 阻塞 join函数
进程是正在运行的程序,程序是程序员编写的一对代码,也就是一堆字符,当这堆代码被系统加载到内存并执行,就有了进程. (需要注意的是:一个程序是可以产生多个程序,就像我们可以同时运行多个QQ程序一样,会形 ...
- 一.定时任务详解https://i.cnblogs.com/EditPosts.aspx
定时任务的详解 h每小时运行 d每天运行 w每周运行 m每个月运行 中毒时查看系统定时任务是否有病毒的脚本. crontab -l 查看用户的定时任务 crontab -e 进入编辑界面增加 ...
- ?:,reverse,vector的基本小结
#include <cstdio> //此代码为网上所复制 #include <iostream> #include <string> #include <s ...
- Layer-level的快速算法
十岁的小男孩 本文为终端移植的一个小章节. Sparse Block Net 本节为优化加速的第二章节,主要介绍Sparse-block net.上章节为OP算子层的加速,本节为层级间的加速,主要针对 ...
- HTML&javaSkcript&CSS&jQuery&ajax(十)
HTML 1.SVG直接嵌入HTML网页 ,SVG 是使用XML描述2D图像的语言,Canvas通过JavaScript来绘制2D <svg xmlns="http://www.w3. ...
- java web----MINA框架使用
前期准备 1.下载 http://mina.apache.org/ 2.将依赖包添加到工程目录下(在工程目录下创建libs(directory目录)) 3.将 slf4j-api-1.7.26.jar ...