传送门


原来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\),此时应该输出的是最后的模数。

  1. #include<bits/stdc++.h>
  2. //this code is written by Itst
  3. using namespace std;
  4. #define int long long
  5. int read(){
  6. int a = 0;
  7. char c = getchar();
  8. while(!isdigit(c)) c = getchar();
  9. while(isdigit(c)){
  10. a = a * 10 + c - 48;
  11. c = getchar();
  12. }
  13. return a;
  14. }
  15. const int _ = 1e5 + 7;
  16. map < int , int > swr;
  17. int hp[_] , p[_] , atk[_] , Atk[_] , N , M;
  18. void exgcd(int a , int b , int &d , int &x , int &y){
  19. b == 0 ? (d = a , x = 1 , y = 0) : (exgcd(b , a % b , d , y , x) , y -= a / b * x);
  20. }
  21. int mul(int x , int y , int MOD){
  22. int sum = 0;
  23. x %= MOD; y %= MOD;
  24. while(y){
  25. if(y & 1) sum = sum + x >= MOD ? sum + x - MOD : sum + x;
  26. x = x + x >= MOD ? x + x - MOD : x + x;
  27. y >>= 1;
  28. }
  29. return sum;
  30. }
  31. signed main(){
  32. #ifndef ONLINE_JUDGE
  33. freopen("in","r",stdin);
  34. //freopen("out","w",stdout);
  35. #endif
  36. for(int T = read() ; T ; --T){
  37. swr.clear();
  38. N = read(); M = read();
  39. for(int i = 1 ; i <= N ; ++i)
  40. hp[i] = read();
  41. bool sp = 1;
  42. for(int i = 1 ; i <= N ; ++i)
  43. sp &= (p[i] = read()) == 1;
  44. for(int i = 1 ; i <= N ; ++i)
  45. atk[i] = read();
  46. for(int i = 1 ; i <= M ; ++i)
  47. ++swr[read()];
  48. for(int i = 1 ; i <= N ; ++i){
  49. auto t = swr.upper_bound(hp[i]);
  50. if(t != swr.begin()) --t;
  51. Atk[i] = t->first;
  52. if(!--t->second) swr.erase(t);
  53. ++swr[atk[i]];
  54. }
  55. int Mod = 1 , ans = 0;
  56. if(sp)
  57. for(int i = 1 ; i <= N ; ++i)
  58. ans = max(ans , hp[i] / Atk[i] + (bool)(hp[i] % Atk[i]));
  59. else
  60. for(int i = 1 ; i <= N ; ++i){
  61. int a , x , y;
  62. exgcd(Atk[i] , p[i] , a , x , y);
  63. if(hp[i] % a){
  64. ans = -1;
  65. break;
  66. }
  67. int mod = p[i] / a;
  68. if(x < 0) x += mod;
  69. int tp = mul(x , hp[i] / a , mod);
  70. int xs = (mod + tp - ans % mod) % mod;
  71. exgcd(Mod , mod , a , x , y);
  72. if(xs % a){
  73. ans = -1;
  74. break;
  75. }
  76. int newMod = Mod / a * mod;
  77. if(x < 0) x += mod / a;
  78. ans = (mul(mul(x , xs / a , mod / a) , Mod , newMod) + ans) % newMod;
  79. Mod = newMod;
  80. }
  81. cout << (ans ? ans : Mod) << endl;
  82. }
  83. return 0;
  84. }

Luogu4774 NOI2018 屠龙勇士 ExCRT的更多相关文章

  1. 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 ...

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

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

  3. Luogu-4774 [NOI2018]屠龙勇士

    这题好像只要会用set/平衡树以及裸的\(Excrt\)就能A啊...然而当时我虽然看出是\(Excrt\)却并不会...今天又学了一遍\(Excrt\),趁机把这个坑给填了吧 现预处理一下,找出每条 ...

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

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

  5. BZOJ_5418_[Noi2018]屠龙勇士_exgcd+excrt

    BZOJ_5418_[Noi2018]屠龙勇士_exgcd+excrt Description www.lydsy.com/JudgeOnline/upload/noi2018day2.pdf 每次用 ...

  6. P4774 [NOI2018]屠龙勇士

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

  7. uoj396 [NOI2018]屠龙勇士

    [NOI2018]屠龙勇士 描述 小 D 最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照编号 1∼n 顺序杀掉 n 条巨龙,每条巨龙拥有一个初始的生命值 ai .同时每条巨龙拥有恢复能 ...

  8. BZOJ5418[Noi2018]屠龙勇士——exgcd+扩展CRT+set

    题目链接: [Noi2018]屠龙勇士 题目大意:有$n$条龙和初始$m$个武器,每个武器有一个攻击力$t_{i}$,每条龙有一个初始血量$a_{i}$和一个回复值$p_{i}$(即只要血量为负数就一 ...

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

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

随机推荐

  1. 【读书笔记】iOS-iCloud介绍

    iCloud是一种面向消费者市场的云存储服务,苹果公司已经做了大量的工作让用户能够平滑过渡到iCloud,不过对开发者而言这意味着新的负担. 怎样使用iCloud? 你可以使用2种方式在你的应用中使用 ...

  2. 【读书笔记】iOS-Interface Builder

    IBOutlet或IBAction符号对编译不产生任何影响,它们只是标记,用于告诉Xcode这些对象可以和UI控件进行关联,以便于在编辑Interface Builder上的UI控件的时候Xcode可 ...

  3. 第二次前端作业grid布局练习

    grid布局 CSS Grid(网格) 布局(又称为 “Grid(网格)” ),是一个二维的基于网格的布局系统,它的目标是完全改变我们基于网格的用户界面的布局方式.CSS 一直用来布局我们的网页,但一 ...

  4. Azure Ubuntu18.04安装lxde桌面记录,Windows远程连接Ubuntu18.04(Linux)

    执行如下命令: 尽量按以下顺序执行,否则可能会发生意向不到的问题(坑) 1.更新数据源 sudo apt-get update 2.更新安装包 sudo apt-get upgrade 3.安装lxd ...

  5. 逻辑回归&线性回归

    # coding:utf-8 import numpy as np from sklearn import linear_model, datasets import matplotlib.pyplo ...

  6. 分享MYSQL中的各种高可用技术

    分享MYSQL中的各种高可用技术 图片和资料来源于姜承尧老师(MYSQL技术内幕作者) mysql高可用各个技术的比较 数据库的可靠指的是数据可靠 数据库可用指的是数据库服务可用 可靠的是数据:例如工 ...

  7. web service && WCF 学习小结

    Web Service和WCF技术都提供了应用程序与应用程序之间的通信.它们都是基于soap消息在客户端和服务端之间进行通信,由于soap消息是一种xml格式,因此传输的数据格式为XML.每次客户端向 ...

  8. 洗礼灵魂,修炼python(19)--文件I/O操作,linecache,fileinput模块

    文件I/O操作 1.什么是文件I/O操作 首先I/O(input/output),即输入/输出端口,然后文件,大家应该都是是什么,一个数据,一个txt或者html文档就是一个文件.文件操作就是对文件进 ...

  9. Servlet (HttpServletResponse)对象

    1.setStatus(int status)方法:用于设置HTTP响应消息的状态码,并生成响应状态行.响应状态行中的状态描述信息直接与状态码相关,HTTP版本由服务器确定,因此只需要通过这个方法设置 ...

  10. ccf--20150903--模板生成系统

    本题思路:首先,使用一个map来存储所有需要替换的关键词,然后,再逐行的替换掉其中的关键词,记住,find每次的其实位置不一样,否则会出现递归生成没有出现关键词就清空掉.最后输出. 题目和代码如下: ...