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^{* ...
随机推荐
- 【代码笔记】Web--使用Chrome来查看网页源代码
一,用Chrome打开百度页面,如图所示. 二,鼠标右键--->显示网页源代码--->如图所示. 三,鼠标右键--->检查---->如图所示.此时可以通过Device来看不同设 ...
- js 中判断变量是数组还是对象,和判断对象是否为空
判断是对象还是数组 var ids={ id:'1',num:'2' } if(Array.isArray(ids) == false) {console.log('不是数组,对象') } else ...
- 部署Redis(脚本安装)
部署Redis(脚本安装) #/bin/bash # DES:Redis Deploy # Author: will_xue # Email:linuxcto@aliyun.com # DATE : ...
- 安卓开发中strings.xml的使用
为了使用方便也是为了代码规范化,我们都将文字信息放在res-values-strings.xml中, 因为开发中需要用到将文字的换行,百度了一下,可以将文字段信息直接在strings.xml文件中换行 ...
- win10下解压版mysql-8.0.12安装教程
内容转载于:https://blog.csdn.net/hust_hqq/article/details/80572133 在他之上添加了一个:服务名无效的解决方法 1.官网下载安装包 网址:http ...
- CentOS乱码解决方法
linux 中文显示乱码解决办法, 其实是有多种情况的, 有一部分是由于终端默认的设置造成的 vi /etc/sysconfig/i18n 将内容改为LANG="zh_CN.GB18030& ...
- 7z常用命令行&7z检测压缩包完整性&7z压缩包错误不执行rsync同步
7Z简介&常用命令 7Z脚本使用说明 7Z检测压缩包完整性脚本 7Z压缩包错误不执行Rsync脚本 1.7Z简介&常用命令 ⑴简介: 7z,全称7-Zip, 是一款开源软件.是目前公认 ...
- table表格(笔记)
<table class="table table-hover2 pick_carTable"> <thead> <tr class="bl ...
- January 22nd, 2018 Week 04th Monday
It is only when you are pursued that you become swift. 唯有在被追赶的时候,你才能真正地奔跑. It is so bad a feeling wh ...
- MATLAB数值积分法
MATLAB数值积分法 作者:凯鲁嘎吉 - 博客园http://www.cnblogs.com/kailugaji/ 一.实验目的 许多工程技术和数学研究中要用到定积分,如果无法直接算不出精确值(如含 ...