「NOI2018」屠龙勇士

首先对于每个龙用哪个剑砍,我们可以用set随便模拟一下得到。

然后求出拿这个剑砍这条龙的答案

\[atk_ix-p_iy=a_i
\]

其中\(atk_i\)是砍第\(i\)条龙的剑的攻击力,\(p_i\)是龙的回复系数,\(a_i\)是初始生命值,然后\(x\)就是单独考虑这个剑砍这个龙的答案。

我们可以拿exgcd去解这个方程,但是冷静分析一波,我们发现回复次数\(y\)需要非负。

然后我们再冷静一波,发现\(p_i\not=1\)的数据都有一个叫性质\(1\)的东西是\(a_i\le p_i\)

在性质\(1\)的情况下,因为\(atk_i\)和\(x\)都是非负的,所以\(y<0\)的时候显然是无解的

然后发现\(p_i\)都等于\(1\)的时候,我们只需要取最大的生命值就可以了

然后快乐的解一下这个方程

注意一件事,可以得到通解\(x\)是在\(\pmod {\frac{p_i}{\gcd(p_i,atk_i)}}\)下的

这样我们就得到了很多个同余方程,然后excrt合并就可以了


Code:

  1. #include <cstdio>
  2. #include <cctype>
  3. #include <algorithm>
  4. #include <set>
  5. #define ll long long
  6. using std::max;
  7. const int SIZE=1<<21;
  8. char ibuf[SIZE],*iS,*iT;
  9. #define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
  10. //#define gc() getchar()
  11. template <class T>
  12. void read(T &x)
  13. {
  14. x=0;char c=gc();
  15. while(!isdigit(c)) c=gc();
  16. while(isdigit(c)) x=x*10+c-'0',c=gc();
  17. }
  18. std::multiset <ll> s;
  19. std::multiset <ll>::iterator it;
  20. const int N=1e5+10;
  21. int n,m;
  22. ll hp[N],p[N],atk[N],A[N],B[N];
  23. ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
  24. void exgcd(ll a,ll b,ll &x,ll &y)
  25. {
  26. if(!b)
  27. {
  28. x=1,y=0;
  29. return;
  30. }
  31. exgcd(b,a%b,x,y);
  32. ll tmp=x;
  33. x=y;
  34. y=tmp-a/b*y;
  35. }
  36. ll mul(ll d,ll k,ll p)
  37. {
  38. ll f=0;
  39. while(k)
  40. {
  41. if(k&1) (f+=d)%=p;
  42. (d+=d)%=p;
  43. k>>=1;
  44. }
  45. return f;
  46. }
  47. void work()
  48. {
  49. ll mx=0;
  50. s.clear();
  51. read(n),read(m);
  52. for(int i=1;i<=n;i++) read(hp[i]);
  53. for(int i=1;i<=n;i++) read(p[i]);
  54. for(int i=1;i<=n;i++) read(atk[i]);
  55. for(int i=1;i<=m;i++)
  56. {
  57. ll x;
  58. read(x);
  59. s.insert(x);
  60. }
  61. for(int i=1;i<=n;i++)
  62. {
  63. ll a,b,c,x,y;
  64. it=s.upper_bound(hp[i]);
  65. if(it==s.begin())
  66. {
  67. b=*it;
  68. s.erase(it);
  69. }
  70. else
  71. {
  72. it--;
  73. b=*it;
  74. s.erase(it);
  75. }
  76. a=b,b=p[i],c=hp[i];
  77. ll d=gcd(a,b);
  78. if(c%d!=0)
  79. {
  80. puts("-1");
  81. return;
  82. }
  83. mx=max(mx,(c-1)/a+1);
  84. exgcd(a,b,x,y);
  85. x=mul(x,c/d,b/d);
  86. x=(x%(b/d)+b/d)%(b/d);
  87. A[i]=x,B[i]=b/d;
  88. s.insert(atk[i]);
  89. }
  90. for(int i=2;i<=n;i++)
  91. {
  92. if(A[i]==A[i-1])
  93. {
  94. B[i]=B[i]/gcd(B[i],B[i-1])*B[i-1];
  95. continue;
  96. }
  97. if(A[i]<A[i-1]) std::swap(A[i],A[i-1]),std::swap(B[i],B[i-1]);
  98. ll a=B[i-1],b=B[i],c=A[i]-A[i-1],d=gcd(a,b),x,y;
  99. if(c%d!=0)
  100. {
  101. puts("-1");
  102. return;
  103. }
  104. exgcd(a,b,x,y);
  105. x=mul(x,c/d,b/d);
  106. B[i]=a/d*b;
  107. A[i]=((A[i-1]+mul(x,B[i-1],B[i]))%B[i]+B[i])%B[i];
  108. }
  109. printf("%lld\n",max(A[n],mx));
  110. }
  111. int main()
  112. {
  113. freopen("dragon.in","r",stdin);
  114. freopen("dragon.out","w",stdout);
  115. int T;read(T);
  116. while(T--) work();
  117. return 0;
  118. }

2019.4.30

「NOI2018」屠龙勇士 解题报告的更多相关文章

  1. 「NOI2018」屠龙勇士

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

  2. 「NOI2018」屠龙勇士(EXCRT)

    「NOI2018」屠龙勇士(EXCRT) 终于把传说中 \(NOI2018D2\) 的签到题写掉了... 开始我还没读懂题目...而且这题细节巨麻烦...(可能对我而言) 首先我们要转换一下,每次的 ...

  3. LOJ #2721. 「NOI2018」屠龙勇士(set + exgcd)

    题意 LOJ #2721. 「NOI2018」屠龙勇士 题解 首先假设每条龙都可以打死,每次拿到的剑攻击力为 \(ATK\) . 这个需要支持每次插入一个数,查找比一个 \(\le\) 数最大的数(或 ...

  4. loj#2721. 「NOI2018」屠龙勇士

    题目链接 loj#2721. 「NOI2018」屠龙勇士 题解 首先可以列出线性方程组 方程组转化为在模p意义下的同余方程 因为不保证pp 互素,考虑扩展中国剩余定理合并 方程组是带系数的,我们要做的 ...

  5. POJ1061 青蛙的约会 和 LOJ2721 「NOI2018」屠龙勇士

    青蛙的约会 Language:Default 青蛙的约会 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 133470 Accep ...

  6. 「NOI2018」屠龙勇士(CRT)

    /* 首先杀每条龙用到的刀是能够确定的, 然后我们便得到了许多形如 ai - x * atki | pi的方程 而且限制了x的最小值 那么exgcd解出来就好了 之后就是扩展crt合并了 因为全T调了 ...

  7. LOJ 2721 「NOI2018」屠龙勇士——扩展中国剩余定理

    题目:https://loj.ac/problem/2721 1.注意别一输入 p[ i ] 就 a[ i ] %= p[ i ] ,因为在 multiset 里找的时候还需要真实值. 2.注意用 m ...

  8. 「FJOI2016」神秘数 解题报告

    「FJOI2016」神秘数 这题不sb,我挺sb的... 我连不带区间的都不会哇 考虑给你一个整数集,如何求这个神秘数 这有点像一个01背包,复杂度和值域有关.但是你发现01背包可以求出更多的东西,就 ...

  9. 「ZJOI2016」大森林 解题报告

    「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...

随机推荐

  1. 百度地图,删除marker,创建marker

    -------------------[删除marker]-----------------------------success: function(data){ if(data.length> ...

  2. 微信小程序学习笔记(三)--框架-逻辑层

    逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈. 开发者写的所有代码最终将会打包成一份 JavaScript 文件,并在小程序启动的时候运行,直到小程序销毁.这一行为类似 Service ...

  3. ASP.NET MVC 分页之HtmlHelper

    using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptograph ...

  4. 概念介绍:IaaS、PaaS、SaaS

    云计算分几层的,分别是Infrastructure(基础设施)-as-a-Service,Platform(平台)-as-a-Service,Sofware(软件)-as -a -Service.基础 ...

  5. 【Tomcat】使用Tomcat部署Spring Boot项目生成的jar包

    介绍 简单来说,Tomcat是一个免费的,用于Java Web应用以及其它Web应用的一个Web服务器.(简单地概括一下,可能有误) 下载与安装 本文章目标是把Spring Boot Web项目生成的 ...

  6. JS-插件编写

    # 参数处理 JS: function plugin_mian_func(options){ var defaluts = { opt1: 'opt1', opt2: 'opt2', opt3: { ...

  7. winform DataGridView的虚模式填充,CellValueNeeded事件的触发条件

    虚模式填充常用来处理大量数据,某个字段的显示问题. DataGridView是.net 2.0新增的表格数据编辑和显示控件,简单的数据显示和编辑,只需直接和数据源绑定就可以了. 对于 一些特殊情况,我 ...

  8. Linux应急响应基础

    文件排查 敏感目录文件分析 tmp目录 命令目录 /usr/bin /usr/sbin 开机启动项 /etc/init.d /etc/init.d是/etc/rc.d/init.d的软链接 文件时间 ...

  9. Django框架(二十九)—— 跨域问题

    目录 跨域问题 一.同源策略 二.CORS(跨域资源共享) 三.CORS两种请求(简单请求与非简单请求) 1.简单请求(一次请求) 2.非简单请求(两次请求) 四.CORS在Django中的应用 1. ...

  10. zabbix监控linux内存

    通过free -m查看当前内存 可用内存:Available memory=free+buffers+cached,即31068=759+66+30243 已用内存:Used memory=used- ...