正题

题目链接:https://www.luogu.com.cn/problem/P4774


题目大意

\(n\)个龙血量为\(a_i\),回复能力为\(p_i\),死亡后掉落剑的攻击力\(t_i\),\(m\)把剑,攻击力为\(b_i\)。

从\(1\)开始打,每次使用不大于当前龙血量的剑中攻击力最低的一把(没有就用攻击力最低的),造成\(x\times atk\)点伤害,然后当前的剑坏掉。

求一个最小的\(x\)使得所有龙被攻击后血量是\(p_i\)的倍数。

\(1\leq n,m\leq 10^5\),满足\(p=1\)或者\(a_i\leq p_i\),所有\(p_i\)的公倍数不超过\(10^{12}\)


解题思路

额,先用\(set\)处理出每个龙用哪把剑打\(c_i\),然后就是对于每条龙的条件就是

\[c_ix\equiv a_i(mod\ p_i),c_ix\geq a_i
\]

后面那个条件可以去掉,我们先求出满足所有\(c_ix\geq a_i\)的最小\(x\),后面再调整。

然后前面那个东西可以用\(EXCRT\)搞了,假设我们上一次求到的答案为\(ans\),目前\(p_i\)的公倍数是\(M\),那么现在的通解就是\(ans+Mx\)。我们需要求出一个\(x\)满足

\[c_i(ans+Mx)\equiv a_i(mod\ p_i)
\]
\[\Rightarrow Mx+p_iy=a_i-c_i\times ans
\]

然后就可以扩欧合并了。


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<set>
#define ll __int128
using namespace std;
ll read(){
ll x=0,f=1; char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
return x*f;
}
void print(ll x)
{if(x>9)print(x/10);putchar(x%10+48);return;}
const ll N=1e5+10;
multiset<ll> s;
ll n,m,T,a[N],p[N],t[N],c[N];
ll exgcd(ll a,ll b,ll &x,ll &y){
if(!b){x=1;y=0;return a;}
ll d=exgcd(b,a%b,x,y);
ll z=x;x=y;y=z-a/b*y;
return d;
}
void work(){
n=read();m=read();s.clear();
ll mx=0;
for(ll i=1;i<=n;i++)a[i]=read();
for(ll i=1;i<=n;i++)p[i]=read();
for(ll i=1;i<=n;i++)t[i]=read();
for(ll i=1;i<=m;i++){
ll x=read();
s.insert(x);
}
for(ll i=1;i<=n;i++){
multiset<ll>::iterator it;
if(a[i]<*s.begin())it=s.begin();
else it=--s.upper_bound(a[i]);
c[i]=*it;s.erase(it);s.insert(t[i]);
mx=max(mx,(a[i]-1)/c[i]+1);
}
ll M=1,x,y,ans=0;
for(ll i=1;i<=n;i++){
ll d=exgcd(M*c[i],p[i],x,y);
ll w=a[i]-c[i]*ans,v=p[i]/d;
if(w%d){puts("-1");return;}
x=w/d*x%v;ans=ans+x*M;
M=M*v;ans=(ans%M+M)%M;
}
if(ans<mx)ans+=(mx-ans+M-1)/M*M;
print(ans);putchar('\n');
}
signed main()
{
scanf("%lld",&T);
while(T--){work();}
return 0;
}

P4774-[NOI2018]屠龙勇士【EXCRT】的更多相关文章

  1. P4774 [NOI2018]屠龙勇士

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

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

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

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

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

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

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

  5. luogu P4774 [NOI2018]屠龙勇士

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

  6. Luogu4774 NOI2018 屠龙勇士 ExCRT

    传送门 原来NOI也会出裸题啊-- 用multiset求出对付每一个BOSS使用的武器威力\(ATK_i\),可以得到\(m\)个式子\(ATK_ix \equiv a_i \mod p_i\) 看起 ...

  7. BZOJ5418:[NOI2018]屠龙勇士(exCRT,exgcd,set)

    Description Input Output Sample Input 23 33 5 74 6 107 3 91 9 10003 23 5 64 8 71 1 11 1 Sample Outpu ...

  8. [NOI2018]屠龙勇士(exCRT)

    首先很明显剑的选择是唯一的,直接用multiset即可. 接下来可以发现每条龙都是一个模线性方程.设攻击第i条龙的剑的攻击力为$s_i$,则$s_ix\equiv a_i\ (mod\ p_i)$. ...

  9. (伪)再扩展中国剩余定理(洛谷P4774 [NOI2018]屠龙勇士)(中国剩余定理,扩展欧几里德,multiset)

    前言 我们熟知的中国剩余定理,在使用条件上其实是很苛刻的,要求模线性方程组\(x\equiv c(\mod m)\)的模数两两互质. 于是就有了扩展中国剩余定理,其实现方法大概是通过扩展欧几里德把两个 ...

  10. BZOJ 5418: [Noi2018]屠龙勇士 EXCRT+multiset

    题解:求解形如 $A[i]ans\equiv b[i](mod$ $p[i])$ 的 $x$ 的最小正整数解. 考虑只有一个等式,那么可以直接化成 $exgcd$ 的形式:$A[i]ans+p[i]y ...

随机推荐

  1. 【mysql】mysql逻辑框架简介及show profile说明

    1.mysql逻辑框架简介 和其它数据库相比,MySQL 有点与众不同,它的架构可以在多种不同场景中应用并发挥良好作用.主要体现在存储引擎的架构上,插件式的存储引擎架构将查询处理和其它的系统任务以及数 ...

  2. LeetCoded第25题题解--K个一组翻转链表--java--链表

    链表 单链表:链表中的每个元素实际上是一个单独的对象,而所有对象都通过每个元素的引用字段链接在一起. 双链表:与单链表不同的是,双链表的每个节点都含有两个引用字段. 链表优点 灵活分配内存空间 能在O ...

  3. Javascript - Vue - vuex

    vuex 这是一个与vue配套的公共数据管理工具,可以将一些需要共享的数据保存到vuex中,以此方便项目中的任何组件都可以从vuex中得到共享数据.cnpm i vuex -S 装包 读取数据 //在 ...

  4. JDBC基础篇(MYSQL)——使用statement执行DQL语句(select)

    注意:其中的JdbcUtil是我自定义的连接工具类:代码例子链接: package day02_statement; import java.sql.Connection; import java.s ...

  5. 三大操作系统对比使用之·Windows10

    时间:2018-10-29 记录:byzqy 本篇是一篇个人对Windows系统使用习惯.技巧和应用推荐的文档,在此记录.分享和后续查询备忘. 打开终端: Win+R,调出"运行" ...

  6. MySQL数据完整性约束

    主键约束 主键可以是表中的某一列,也可以是表中的多个列所构成的一个组合:其中,由多个列组合而成的主键也称为复合主键.在MySQL中,主键列必须遵守以下规则. (1)每一个表只能定义一个主键. (2)唯 ...

  7. 基于Appium,封装自己的常用方法

    Appium算是老牌移动端App自动化测试工具了,在使用它的过程中,使用者经常会根据个人习惯,把较常用的方法封装在一起,方便调用.以下是我的封装,希望对你有启发. from typing import ...

  8. Linux高级之语句表达式

    表达式 表达式和语句是 C 语言中的基础概念.什么是表达式呢?表达式就是由一系列操作符和操作数构成的式子.操作符可以是 C 语言标准规定的各种算术运算符.逻辑运算符.赋值运算符.比较运算符等.操作数可 ...

  9. TypeScript 中高级类型的理解?有哪些?

    一.是什么 除了string.number.boolean 这种基础类型外,在 typescript 类型声明中还存在一些高级的类型应用 这些高级类型,是typescript为了保证语言的灵活性,所使 ...

  10. JDBC使用案例

    一.结果集中获取数据并对实体set值,封装成对象返回: 2.封装JDBC工具类 只要执行一次的,如读取配置文件,则写静态代码块: 异常抛出要写明方法才可以throw,静态代码块异常只能捕捉try ca ...