【NOI 2018】屠龙勇士(扩欧)
题意理解错了。。。
一把剑打一条龙,打了$x$次后如果龙不死,你就Game Over了。
显然,面对每条龙使用的剑是固定的,如果所有龙中有一条没打死你就挂了。
可以知道,可行的答案集合就是所有龙的可行集合的交集。
考虑当前面对第$i$条龙,若要打死它,$x$满足条件:$a_{i} - x * v_{i} + y * p_{i} = 0$,其中$a$是血量,$v$是攻击力,$p$是恢复力,$y$是某非负整数。
可以把它转化为同余式:$a_{i} \equiv x * v_{i} (mod \; p_{i})$。我们要找出满足该条件的$x$的最小正整数值。
通常情况下,只要先算$v_{i}$在$(mod \; p_{i})$意义下的逆元即可,但此时两者不互质,不一定存在逆元,根据数论某定理:$ a * c \equiv b * c (mod \; m) \Rightarrow a \equiv b (mod \; m / ( c , m ) $,我们先除去三者的$gcd$,再求逆元就可以了,如果此时仍然没有逆元,则无解。(这里有一个要注意的事情,当$p_{i}=1$的时候会出点问题,特判就可以了)
可以发现,$x$可以的取值是一个等差数列,我们需要把$n$个等差数列合并起来,取它们的交集。
假设我们即将合并的两个等差数列为$(a_{s}, d_{s}),(a_{i},d_{i})$,其中$a$为首项,$d$为公差。
合并后的公差比较好算:$lcm(d_{s},d_{i})$。主要考虑如何求第一个数同时出现在两个等差数列中了。
可以列出以下等式:$a_{s} + x * d_{s} = a_{i} + y * d_{i}$,其中$x, y$都是某个非负整数。
移项转化为同余式:$x * d_{s} \equiv a_{i} - a_{s} (mod \; d_{i})$,和刚刚的套路一样就可以解出$x$的值啦。
最后显然$a_{s}$就是我们想要的答案。(提示:由于中间答案过大,使用中精度存储,也可以用快速乘)
Update :
求同余式$x * a \equiv b (mod \; p)$的另一种思路,设$d = gcd(a, p)$,那有解当且仅当$d | b$。具体证明就是扩展欧几里得相关。
那该同余方程等价于$x * \frac{a}{d} \equiv \frac{b}{d} (mod \; \frac{p}{d})$。此时由于$\frac{b}{d}$一定与$\frac{p}{d}$互质,通过求逆元直接解出$x$即可。
$\bigodot$技巧&套路:
- 基础数论,同余式$x * a \equiv b (mod \; p)$求解的技巧。
#include <cstdio>
#include <set> typedef long long LL;
const int N = ; int tc, n, m;
LL ai[N], di[N], a[N], p[N], b[N], v[N];
std::multiset<LL> S; inline LL Mul(LL a, LL b, LL p) {
a %= p; b %= p;
LL a0 = a & , a1 = a >> ;
return (((a1 * b % p) << ) + a0 * b) % p;
}
LL Ex_gcd(LL a, LL b, LL &x, LL &y) {
if (b == ) return x = , y = , a;
LL g = Ex_gcd(b, a % b, y, x);
y -= a / b * x;
return g;
} inline LL Get(LL x, LL re = ) {
auto it = S.upper_bound(x);
if (it != S.begin()) --it;
re = *it; S.erase(it);
return re;
} int main() {
scanf("%d", &tc);
for (; tc; --tc) {
S.clear();
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", &b[i]);
for (int i = ; i <= m; ++i) scanf("%lld", &v[i]), S.insert(v[i]); LL as = , ps = ;
for (int i = ; i <= n; ++i) {
LL vi = Get(a[i]), x, y, ai, pi;
LL d = Ex_gcd(vi, p[i], x, y);
if (a[i] % d != ) {
as = -; break;
}
x = (x % (p[i] / d) + p[i] / d) % (p[i] / d);
ai = Mul(a[i] / d, x, p[i] / d);
pi = p[i] / d;
if (p[i] == ) ai = a[i] / vi + (bool)(a[i] % vi);
S.insert(b[i]);
if (pi == ) {
if (as < ai) {
LL bl = (ai - as) / ps + (bool)((ai - as) % ps);
as = as + bl * ps;
}
continue;
}
LL dir = ((ai - as) % pi + pi) % pi;
d = Ex_gcd(ps, pi, x, y);
if (dir % d != ) {
as = -; break;
}
x = (x % (pi / d) + pi / d) % (pi / d);
LL nx = Mul(dir / d, x, pi / d);
as = as + nx * ps;
ps = ps / d * pi;
} printf("%lld\n", as);
} return ;
}
【NOI 2018】屠龙勇士(扩欧)的更多相关文章
- [LOJ 2721][UOJ 396][BZOJ 5418][NOI 2018]屠龙勇士
[LOJ 2721][UOJ 396][BZOJ 5418][NOI 2018]屠龙勇士 题意 题面好啰嗦啊直接粘LOJ题面好了 小 D 最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照 ...
- 洛谷P4774 [NOI2018]屠龙勇士 [扩欧,中国剩余定理]
传送门 思路 首先可以发现打每条龙的攻击值显然是可以提前算出来的,拿multiset模拟一下即可. 一般情况 可以搞出这么一些式子: \[ atk_i\times x=a_i(\text{mod}\ ...
- NOI 2018 屠龙勇士 (拓展中国剩余定理excrt+拓展欧几里得exgcd)
题目大意:略 真是一波三折的一道国赛题,先学了中国剩余定理,勉强看懂了模板然后写的这道题 把取出的宝剑攻击力设为T,可得Ti*x=ai(mod pi),这显然是ax=c(mod b)的形式 这部分用e ...
- NOI 2018网络同步赛(游记?)
刚中考完那段时间比较无聊,报名了一个同步赛,报完名才发现成绩单是要挂到网上的,而且因为报的早给了一个很靠前的考号...那布星啊,赶紧学点东西,于是在一周内学了网络流,Treap以及一些数论. Day1 ...
- 洛谷 P4774 [NOI2018] 屠龙勇士
链接:P4774 前言: 交了18遍最后发现是多组数据没清空/ll 题意: 其实就是个扩中. 分析过程: 首先发现根据题目描述的选择剑的方式,每条龙对应的剑都是固定的,有查询前驱,后继(在该数不存在前 ...
- NOI2018屠龙勇士(扩展CRT + splay(multiset))
QWQ 一到假期就颓废 哎 今年新鲜出炉的NOI题,QwQ同步赛的时候写的,后来交了一发洛谷,竟然过了 首先 根据题目,我们很容易得到,假设对应每一条龙的剑的攻击力是\(atk\)的话 \[a_i-x ...
- 【POJ】2115 C Looooops(扩欧)
Description A Compiler Mystery: We are given a C-language style for loop of type for (variable = A; ...
- BZOJ5418[Noi2018]屠龙勇士——exgcd+扩展CRT+set
题目链接: [Noi2018]屠龙勇士 题目大意:有$n$条龙和初始$m$个武器,每个武器有一个攻击力$t_{i}$,每条龙有一个初始血量$a_{i}$和一个回复值$p_{i}$(即只要血量为负数就一 ...
- 「NOI2018」屠龙勇士(EXCRT)
「NOI2018」屠龙勇士(EXCRT) 终于把传说中 \(NOI2018D2\) 的签到题写掉了... 开始我还没读懂题目...而且这题细节巨麻烦...(可能对我而言) 首先我们要转换一下,每次的 ...
- LOJ #2721. 「NOI2018」屠龙勇士(set + exgcd)
题意 LOJ #2721. 「NOI2018」屠龙勇士 题解 首先假设每条龙都可以打死,每次拿到的剑攻击力为 \(ATK\) . 这个需要支持每次插入一个数,查找比一个 \(\le\) 数最大的数(或 ...
随机推荐
- 通过扩展方法简化UnityAPI调用
通过扩展方法简化UnityAPI调用 扩展方法unity apiapi简化 通过扩展方法简化UnityAPI调用 能省一秒是一秒,时间就是金钱,没人愿意把时间花在冗长的coding上
- 微软Word制作自己的模板
我们在用Word的时候,很多时候需要一定的格式. 这个时候,*.dotx文件出场了!它将带给我们自己的模板. 步骤: 首先,新建一个文档,选择空白文档: 图片大就大吧,不要在意这些细节. 编辑一下,保 ...
- GitHub笔记(四)——标签管理
五 标签管理 1 打标签.默认master $ git tag v1.0 要对add merge这次提交打标签,它对应的commit id是f52c633,敲入命令: $ git tag v0.9 f ...
- 07-matplotlib-箱线图
import numpy as np import matplotlib.pyplot as plt ''' 箱形图(Box-plot)又称为盒须图,盒式图,或 箱线图: 是一种用在显示一组数据分散情 ...
- Python参数传递,既不是传值也不是传引用
面试的时候,有没有被问到Python传参是传引用还是传值这种问题?有没有听到过Python传参既不是传值也不是传引用这种说法?一个小小的参数默认值也可能让代码出现难以查找的bug? 如果你也遇到过上面 ...
- 利用cocoapods创建基于git的私有库Spec Repo
上一篇文章记录了我利用cocoapods创建基于SVN的私有库的全部过程,今天我再记录一下基于git创建的过程. 整体先说明一下创建一个私有的podspec包括如下那么几个步骤: 创建并设置一个私有的 ...
- spring boot的maven项目报404错误
$.ajax({ async: false, type: "POST", url:'searchFileSource', contentType : "applicati ...
- Data truncation: Truncated incorrect DOUBLE value:
在写sql查询语句queryRunner.update(connection,"update account set balance=? where name=?",account ...
- 关于datatable的数据绑定问题
最近做项目掉在数据绑定这个小坑里了,最后发现问题其实很简单,只是官方的文档描述可能不太清除导致的吧.首先贴上官网地址:http://www.datatables.club/ 关于这个插件的简单使用就不 ...
- linux上传的命令
pscp D:\apache-tomcat-8.0.38\webapps\GameDataServer.zip root@112.74.32.215:/usr/local/tools/tomcat/a ...