Luogu4774 NOI2018 屠龙勇士 ExCRT
原来NOI也会出裸题啊……
用multiset求出对付每一个BOSS使用的武器威力\(ATK_i\),可以得到\(m\)个式子\(ATK_ix \equiv a_i \mod p_i\)
看起来可以直接魔改式子了……
等一下!如果\(a_i > p_i\),\(ATK_ix<a_i\)没把BOSS打死怎么办QAQ
看数据范围,没有特性1(\(a_i \leq p_i\))的点似乎\(p_i=1\)?那不只要保证攻击次数能够把所有BOSS血量打到\(\leq 0\)就行了,,,于是这个顾虑就消除了(虽然要写数据分治)
考虑上面得到的式子,很像ExCRT,但ExCRT的式子都长\(x \equiv b_i \mod p_i\),这里的式子不长这样。于是考虑改式子。
如果\(gcd(ATK_i , p_i) \not\mid a_i\),显然原式无解。
当\(gcd(ATK_i , p_i) \mid a_i\)时,求出\(ATK_ix + p_iy = gcd(ATK_i,p_i)\)的一组解\((x_1,y_1)\),那么\(ATK_ix + p_iy = a_i\)的一组解就是\((\frac{x_1a_i}{gcd(ATK_i,p_i)} , \frac{y_1a_i}{gcd(ATK_i,p_i)})\)。
那么\(ATK_ix \equiv a_i \mod p_i\)的通解就是\(x \equiv \frac{x_1a_i}{gcd(ATK_i,p_i)} \mod \frac{p_i}{gcd(ATK_i,p_i)}\)。
这个式子长得跟ExCRT的式子相同了,直接套板子即可。
值得注意的是,因为模数可能超过int,导致可能出现乘法爆long long。解决方案是log龟速乘/long double型快速乘/__int128
还有一个细节是:因为\(a_i \leq p_i\)所以最后答案可能是\(0\),此时应该输出的是最后的模数。
#include<bits/stdc++.h>
//this code is written by Itst
using namespace std;
#define int long long
int read(){
int a = 0;
char c = getchar();
while(!isdigit(c)) c = getchar();
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return a;
}
const int _ = 1e5 + 7;
map < int , int > swr;
int hp[_] , p[_] , atk[_] , Atk[_] , N , M;
void exgcd(int a , int b , int &d , int &x , int &y){
b == 0 ? (d = a , x = 1 , y = 0) : (exgcd(b , a % b , d , y , x) , y -= a / b * x);
}
int mul(int x , int y , int MOD){
int sum = 0;
x %= MOD; y %= MOD;
while(y){
if(y & 1) sum = sum + x >= MOD ? sum + x - MOD : sum + x;
x = x + x >= MOD ? x + x - MOD : x + x;
y >>= 1;
}
return sum;
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
for(int T = read() ; T ; --T){
swr.clear();
N = read(); M = read();
for(int i = 1 ; i <= N ; ++i)
hp[i] = read();
bool sp = 1;
for(int i = 1 ; i <= N ; ++i)
sp &= (p[i] = read()) == 1;
for(int i = 1 ; i <= N ; ++i)
atk[i] = read();
for(int i = 1 ; i <= M ; ++i)
++swr[read()];
for(int i = 1 ; i <= N ; ++i){
auto t = swr.upper_bound(hp[i]);
if(t != swr.begin()) --t;
Atk[i] = t->first;
if(!--t->second) swr.erase(t);
++swr[atk[i]];
}
int Mod = 1 , ans = 0;
if(sp)
for(int i = 1 ; i <= N ; ++i)
ans = max(ans , hp[i] / Atk[i] + (bool)(hp[i] % Atk[i]));
else
for(int i = 1 ; i <= N ; ++i){
int a , x , y;
exgcd(Atk[i] , p[i] , a , x , y);
if(hp[i] % a){
ans = -1;
break;
}
int mod = p[i] / a;
if(x < 0) x += mod;
int tp = mul(x , hp[i] / a , mod);
int xs = (mod + tp - ans % mod) % mod;
exgcd(Mod , mod , a , x , y);
if(xs % a){
ans = -1;
break;
}
int newMod = Mod / a * mod;
if(x < 0) x += mod / a;
ans = (mul(mul(x , xs / a , mod / a) , Mod , newMod) + ans) % newMod;
Mod = newMod;
}
cout << (ans ? ans : Mod) << endl;
}
return 0;
}
Luogu4774 NOI2018 屠龙勇士 ExCRT的更多相关文章
- 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 ...
- [NOI2018]屠龙勇士(exCRT)
首先很明显剑的选择是唯一的,直接用multiset即可. 接下来可以发现每条龙都是一个模线性方程.设攻击第i条龙的剑的攻击力为$s_i$,则$s_ix\equiv a_i\ (mod\ p_i)$. ...
- Luogu-4774 [NOI2018]屠龙勇士
这题好像只要会用set/平衡树以及裸的\(Excrt\)就能A啊...然而当时我虽然看出是\(Excrt\)却并不会...今天又学了一遍\(Excrt\),趁机把这个坑给填了吧 现预处理一下,找出每条 ...
- BZOJ 5418: [Noi2018]屠龙勇士 EXCRT+multiset
题解:求解形如 $A[i]ans\equiv b[i](mod$ $p[i])$ 的 $x$ 的最小正整数解. 考虑只有一个等式,那么可以直接化成 $exgcd$ 的形式:$A[i]ans+p[i]y ...
- BZOJ_5418_[Noi2018]屠龙勇士_exgcd+excrt
BZOJ_5418_[Noi2018]屠龙勇士_exgcd+excrt Description www.lydsy.com/JudgeOnline/upload/noi2018day2.pdf 每次用 ...
- P4774 [NOI2018]屠龙勇士
P4774 [NOI2018]屠龙勇士 先平衡树跑出打每条龙的atk t[] 然后每条龙有\(xt \equiv a[i](\text{mod }p[i])\) 就是\(xt+kp[i]=a[i]\) ...
- uoj396 [NOI2018]屠龙勇士
[NOI2018]屠龙勇士 描述 小 D 最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照编号 1∼n 顺序杀掉 n 条巨龙,每条巨龙拥有一个初始的生命值 ai .同时每条巨龙拥有恢复能 ...
- BZOJ5418[Noi2018]屠龙勇士——exgcd+扩展CRT+set
题目链接: [Noi2018]屠龙勇士 题目大意:有$n$条龙和初始$m$个武器,每个武器有一个攻击力$t_{i}$,每条龙有一个初始血量$a_{i}$和一个回复值$p_{i}$(即只要血量为负数就一 ...
- [洛谷P4774] [NOI2018]屠龙勇士
洛谷题目链接:[NOI2018]屠龙勇士 因为markdown复制过来有点炸格式,所以看题目请戳上面. 题解: 因为杀死一条龙的条件是在攻击\(x\)次,龙恢复\(y\)次血量\((y\in N^{* ...
随机推荐
- video自动禁止全屏
在微信浏览器.苹果等其他浏览器,里面使用video标签,会自动变成全屏,改成下面就好了,起码可以在video标签之上加入其他元素 webkit-playsinline playsinline x ...
- JMeter 配置元件之计数器Counter
配置元件之计数器Counter by:授客 QQ:1033553122 测试环境 apache-jmeter-2.13 1. 计数器简介 允许用户创建一个在线程组范围之内都可以被引用的计数器. ...
- Android事件总线(三)otto用法全解析
前言 otto 是 Square公司发布的一个发布-订阅模式框架,它基于Google Guava 项目中的event bus模块开发,针对Android平台做了优化和加强.虽然Square已经停止了对 ...
- React 表单与事件
一个简单是实例 在实例中我们设置了输入框 input 值value = {this.state.data}.在输入框值发生变化时我们可以更新 state.我们可以使用 onChange 事件来监听 i ...
- 使用wxpy自动发送微信消息
思路整理:1.进入心灵鸡汤网页,使用python获取心灵鸡汤内容 2.登陆微信,找到需要发送的朋友 3.发送获取的内容 1.获取心灵鸡汤的内容 如下图,获取第一条鸡汤 实现如下: 2.登陆微信,搜索朋 ...
- 洗礼灵魂,修炼python(13)--模块random,math,pickle
random 1.作用: random模块用于生成随机数 2.常用函数: random:用于生成一个0到1的随机符点数: 0 <= n < 1.0 uniform(a, b):用于生成一个 ...
- Spring Boot 使用 ServletFileUpload上传文件失败,upload.parseRequest(request)为空
使用Apache Commons FileUpload组件上传文件时总是返回null,调试发现ServletFileUpload对象为空,在Spring Boot中有默认的文件上传组件,在使用Serv ...
- 第五章 绘图基础(BEZIER)
/*----------------------------- BEZIER.C -- Bezier Splines Demo (c) Charles Petzold, 1998 ---------- ...
- Python学习—Pycharm连接mysql服务器
安装pymysql pip3 install pymysql 安装Mysql客户端驱动(基于Pycharm工具) 点击download,下载mysql驱动 等待驱动安装成功后,点击OK即可 创建数据库 ...
- sql2008和sql2012混合安装后打开SQL Server 配置管理器查看出现“远程过程调用失败”0x800706be
sql2008和sql2012混合安装后打开SQL Server 配置管理器SQL Server服务出现“远程过程调用失败”0x800706be 网上很多人都说这个解决方案,通过卸载“Microsof ...