博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NOI2018Day2T1 屠龙勇士 set 扩展欧几里德 中国剩余定理
阅读量:4962 次
发布时间:2019-06-12

本文共 3073 字,大约阅读时间需要 10 分钟。

原文链接https://www.cnblogs.com/zhouzhendong/p/NOI2018Day2T1.html

题意

 

题解

  首先我们仔细看一看样例可以发现如果一回合打不过巨龙就输了。

  所以每一回合都要赢。所以每一次选择的宝剑都是可以提前预知的。

  我们用个 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 
#include
#include
#include
#include
#include
#include
#include
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
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
:: iterator p=S.begin(); if ((*p)

  

转载于:https://www.cnblogs.com/zhouzhendong/p/NOI2018Day2T1.html

你可能感兴趣的文章
Strict Standards: Only variables should be passed by reference
查看>>
hiho_offer收割18_题解报告_差第四题
查看>>
AngularJs表单验证
查看>>
静态方法是否属于线程安全
查看>>
02号团队-团队任务3:每日立会(2018-12-05)
查看>>
SQLite移植手记1
查看>>
C# windows程序应用与JavaScript 程序交互实现例子
查看>>
HashMap详解
查看>>
js05-DOM对象二
查看>>
mariadb BINLOG_FORMAT = STATEMENT 异常
查看>>
C3P0 WARN: Establishing SSL connection without server's identity verification is not recommended
查看>>
iPhone在日本最牛,在中国输得最慘
查看>>
动态方法决议 和 消息转发
查看>>
js 基础拓展
查看>>
C#生成随机数
查看>>
Android应用程序与SurfaceFlinger服务的连接过程分析
查看>>
Java回顾之多线程
查看>>
sqlite
查看>>
机电行业如何进行信息化建设
查看>>
9、总线
查看>>