POJ1061 青蛙的约会 和 LOJ2721 「NOI2018」屠龙勇士
青蛙的约会
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 133470 | Accepted: 29610 |
Description
我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。
Input
Output
Sample Input
1 2 3 4 5
Sample Output
4
Source
分析
设\(a=m-n,b=y-x\),那么要解决的方程是
\Rightarrow ax+ly=b
\]
那么exgcd就行了,时间复杂度log级别。
#include<iostream>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
ll exgcd(ll a,ll b,ll&x,ll&y){
if(!b) return x=1,y=0,a;
ll g=exgcd(b,a%b,y,x);
return y-=a/b*x,g;
}
int main(){
// freopen(".in","r",stdin),freopen(".out","w",stdout);
ll x,y,m,n,l;
read(x),read(y),read(m),read(n),read(l);
ll a=m-n,b=y-x;
if(a<0) a=-a,b=-b;
ll g=exgcd(a,l,x,y);
if(b%g) return puts("Impossible"),0;
ll ans=x*(b/g);
printf("%lld\n",(ans%(l/g)+l/g)%(l/g));
return 0;
}
「NOI2018」屠龙勇士
题目描述
小D 最近在网上发现了一款小游戏。游戏的规则如下:
游戏的目标是按照编号$1 \rightarrow n$ 顺序杀掉$n$ 条巨龙,每条巨龙拥有一个初始的生命值$a_i$ 。同时每条巨龙拥有恢复能力,当其使用恢复能力时,它的生命值就会每次增加 $p_i$ ,直至生命值非负。只有在攻击结束后且当生命值恰好为 $0$ 时它才会死去。
游戏开始时玩家拥有$m$ 把攻击力已知的剑,每次面对巨龙时,玩家只能选择一
把剑,当杀死巨龙后这把剑就会消失,但作为奖励,玩家会获得全新的一把剑。
小D 觉得这款游戏十分无聊,但最快通关的玩家可以获得ION2018 的参赛资格,
于是小D 决定写一个笨笨的机器人帮她通关这款游戏,她写的机器人遵循以下规则:每次面对巨龙时,机器人会选择当前拥有的,攻击力不高于巨龙初始生命值中攻击力最大的一把剑作为武器。如果没有这样的剑,则选择攻击力最低的一把剑作为武器。
机器人面对每条巨龙,它都会使用上一步中选择的剑攻击巨龙固定的$x$ 次,使巨龙的生命值减少$x \times ATK$ 。
之后,巨龙会不断使用恢复能力,每次恢复$p_i$ 生命值。若在使用恢复能力前或某一次恢复后其生命值为$0$ ,则巨龙死亡,玩家通过本关。
那么显然机器人的攻击次数是决定能否最快通关这款游戏的关键。小 D 现在得知了每条巨龙的所有属性,她想考考你,你知道应该将机器人的攻击次数$x$ 设置为多少,才能用最少的攻击次数通关游戏吗?
当然如果无论设置成多少都无法通关游戏,输出$-1$ 即可。
输入输出格式
输入格式:
从文件dragon.in 中读入数据。
第一行一个整数T ,代表数据组数。
接下来T 组数据,每组数据包含$5$ 行。
每组数据的第一行包含两个整数,$n$ 和$m$ ,代表巨龙的数量和初始剑的数量;
接下来一行包含$n$ 个正整数,第$i$ 个数表示第$i$ 条巨龙的初始生命值$a_i$ ;
接下来一行包含$n$ 个正整数,第$i$ 个数表示第$i$ 条巨龙的恢复能力$p_i$ ;
接下来一行包含$n$ 个正整数,第$i$ 个数表示杀死第$i$ 条巨龙后奖励的剑的攻击力;
接下来一行包含$m$ 个正整数,表示初始拥有的$m$ 把剑的攻击力。
输出格式:
输出到文件dragon.out 中。
一共$T$ 行。
第$i$ 行一个整数,表示对于第$i$ 组数据,能够使得机器人通关游戏的最小攻击次数$x$ ,如果答案不存在,输出$-1$。
输入输出样例
说明
第一组数据:
开始时拥有的剑的攻击力为$\{1,9,10\}$,第$1$ 条龙生命值为$3$,故选择攻击力为$1$的剑,攻击$59$ 次,造成$59$ 点伤害,此时龙的生命值为$-56$,恢复14 次后生命值恰好为$0$,死亡。
攻击力为$1$ 的剑消失,拾取一把攻击力为$7$ 的剑,此时拥有的剑的攻击力为
$\{7,9,10\}$,第2 条龙生命值为$5$,故选择攻击力为$7$ 的剑,攻击$59$ 次,造成$413$点伤害,此时龙的生命值为$-408$,恢复$68$ 次后生命值恰好为$0$,死亡。此时拥有的剑的攻击力为$\{3,9,10\}$,第$3$ 条龙生命值为$7$,故选择攻击力为$3$ 的剑,攻击$59$ 次,造成$177$ 点伤害,此时龙的生命值为$-170$,恢复$17$ 次后生命值恰好为0,死亡。
没有比$59$ 次更少的通关方法,故答案为$59$。
第二组数据:
不存在既能杀死第一条龙又能杀死第二条龙的方法,故无法通关,输出$-1$。
【子任务】
测试点编号 | $n$ | $m$ | $p_i$ | $a_i$ | 攻击力 | 其他限制 |
---|---|---|---|---|---|---|
1 | $\le 10^5$ | $=1$ | $=1$ | $\le 10^5$ | $=1$ | 无 |
2 | $\le 10^5$ | $=1$ | $=1$ | $\le 10^5$ | $=1$ | 无 |
3 | $\le 10^5$ | $=1$ | $=1$ | $\le 10^5$ | $\le 10^5$ | 无 |
4 | $\le 10^5$ | $=1$ | $=1$ | $\le 10^5$ | $\le 10^5$ | 无 |
5 | $\le 10^3$ | $\le 10^3$ | $\le 10^5$ | $\le 10^5$ | $\le 10^5$ | 特性 1、特性 2 |
6 | $\le 10^3$ | $\le 10^3$ | $\le 10^5$ | $\le 10^5$ | $\le 10^5$ | 特性 1、特性 2 |
7 | $\le 10^3$ | $\le 10^3$ | $\le 10^5$ | $\le 10^5$ | $\le 10^5$ | 特性 1、特性 2 |
8 | $=1$ | $=1$ | $\le 10^8$ | $\le 10^8$ | $\le 10^6$ | 特性 1 |
9 | $=1$ | $=1$ | $\le 10^8$ | $\le 10^8$ | $\le 10^6$ | 特性 1 |
10 | $=1$ | $=1$ | $\le 10^8$ | $\le 10^8$ | $\le 10^6$ | 特性 1 |
11 | $=1$ | $=1$ | $\le 10^8$ | $\le 10^8$ | $\le 10^6$ | 特性 1 |
12 | $=1$ | $=1$ | $\le 10^8$ | $\le 10^8$ | $\le 10^6$ | 特性 1 |
13 | $=1$ | $=1$ | $\le 10^8$ | $\le 10^8$ | $\le 10^6$ | 特性 1 |
14 | $=10^5$ | $=10^5$ | $=1$ | $\le 10^8$ | $\le 10^6$ | 无特殊限制 |
15 | $=10^5$ | $=10^5$ | $=1$ | $\le 10^8$ | $\le 10^6$ | 无特殊限制 |
16 | $\le 10^5$ | $\le 10^5$ | 所有 $p_i$ 是质数 | $\le 10^{12}$ | $\le 10^6$ | 特性 1 |
17 | $\le 10^5$ | $\le 10^5$ | 所有 $p_i$ 是质数 | $\le 10^{12}$ | $\le 10^6$ | 特性 1 |
18 | $\le 10^5$ | $\le 10^5$ | 无特殊限制 | $\le 10^{12}$ | $\le 10^6$ | 特性 1 |
19 | $\le 10^5$ | $\le 10^5$ | 无特殊限制 | $\le 10^{12}$ | $\le 10^6$ | 特性 1 |
20 | $\le 10^5$ | $\le 10^5$ | 无特殊限制 | $\le 10^{12}$ | $\le 10^6$ | 特性 1 |
特性 1 是指:对于任意的 $i$,$a_i \le p_i$。
特性 2 是指:$\operatorname{lcm}(p_i) \le 10^6$,即所有 $p_i$ 的最小公倍数不大于 $10^6$。
对于所有的测试点,$T \le 5$,所有武器的攻击力 $\le 10^6$,所有 $p_i$ 的最小公倍数 $\le 10^{12}$。
保证 $ T, n, m $ 均为正整数。
【提示】
你所用到的中间结果可能很大,注意保存中间结果的变量类型。
题解
仔细阅读发现给每条龙的剑的攻击力是固定的,直接用multiset维护即可。
然后就是要求形如\(atk_i*x+p_i*y=a_i\)的方程组的最小解。
联想到EXCRT解的方程组的形式\(x\equiv a_i\ (\bmod p_i)\),和线性同余方程\(ax+by=c\)的通解的形式\(x=\frac{c}{d}x_0+t\frac{b}{d},d=\gcd(a,b)\),
那么这种方程组的解\(x=\frac{a_i}{d}x_0+t\frac{p_i}{d},d=\gcd(atk_i,p_i)\)可以看成同余式\(x\equiv \frac{a_i}{d}x_0\ (\bmod \frac{p_i}{d})\),然后这就变成了EXCRT解决的问题。
然后推程序里面处理的式子,比较繁琐,没什么意义,不写了。
要注意\(a_i>p_i\)的情况,取模后相当于\(a_i\)变小了,这样会导致\(x\)的解变小。所以要注意\(x\geq\lceil\frac a k\rceil\)。可以求出\(\max\{\lceil\frac a k\rceil\}\),如果最后总方程的\(c\)小于它,则要补至满足条件的最小值,用式子写一下大概是\(c+m\lceil\frac{\max-c}{m} \rceil\)。
注意数据范围,会爆long long
的地方用快速乘。注意处理负数。
时间复杂度\(O(n\log n)\)
#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;
co int N=1e5+1;
ll a[N],p[N],b[N],X,Y,G;
multiset<ll> s;
multiset<ll>::iterator it;
void exgcd(ll a,ll b){
if(!b) {
X=1,Y=0,G=a;
return;
}
exgcd(b,a%b);
int t=X;X=Y,Y=t-(a/b)*Y;
}
ll mul(ll b,ll k,ll m){
ll a=0;
for(;k;k>>=1,b=(b<<1)%m)
if(k&1) a=(a+b)%m;
return a;
}
void dragon(){
ll n=read<ll>(),m=read<ll>();
for(int i=1;i<=n;++i) read(a[i]);
for(int i=1;i<=n;++i) read(p[i]);
for(int i=1;i<=n;++i) read(b[i]);
s.clear();
for(int i=1;i<=m;++i) s.insert(read<ll>());
ll mx=0,c=0;m=1;
for(int i=1;i<=n;++i){
it=s.upper_bound(a[i]);
if(it!=s.begin()) --it;
ll k=*it;s.erase(it),s.insert(b[i]);
mx=max(mx,(a[i]-1)/k+1);
k%=p[i],a[i]%=p[i];
if(!k&&a[i]) return puts("-1"),void();
if(!k&&!a[i]) continue;
exgcd(k,p[i]);
if(a[i]%G) return puts("-1"),void();
p[i]/=G,a[i]=mul(a[i]/G,(X%p[i]+p[i])%p[i],p[i]);
exgcd(m,p[i]);
if((a[i]-c)%G) return puts("-1"),void();
m=m/G*p[i],c=(c+mul(mul(m/p[i],((a[i]-c)%m+m)%m,m),(X%m+m)%m,m))%m;
}
printf("%lld\n",c>=mx?c:c+m*(mx-c-1)/m+1);
}
int main(){
freopen("dragon.in","r",stdin),freopen("dragon.out","w",stdout);
for(int t=read<int>();t--;) dragon();
return 0;
}
POJ1061 青蛙的约会 和 LOJ2721 「NOI2018」屠龙勇士的更多相关文章
- 「NOI2018」屠龙勇士(EXCRT)
「NOI2018」屠龙勇士(EXCRT) 终于把传说中 \(NOI2018D2\) 的签到题写掉了... 开始我还没读懂题目...而且这题细节巨麻烦...(可能对我而言) 首先我们要转换一下,每次的 ...
- LOJ #2721. 「NOI2018」屠龙勇士(set + exgcd)
题意 LOJ #2721. 「NOI2018」屠龙勇士 题解 首先假设每条龙都可以打死,每次拿到的剑攻击力为 \(ATK\) . 这个需要支持每次插入一个数,查找比一个 \(\le\) 数最大的数(或 ...
- loj#2721. 「NOI2018」屠龙勇士
题目链接 loj#2721. 「NOI2018」屠龙勇士 题解 首先可以列出线性方程组 方程组转化为在模p意义下的同余方程 因为不保证pp 互素,考虑扩展中国剩余定理合并 方程组是带系数的,我们要做的 ...
- 「NOI2018」屠龙勇士
「NOI2018」屠龙勇士 题目描述 小\(D\)最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照编号\(1-n\)顺序杀掉\(n\) 条巨龙,每条巨龙拥有一个初始的生命 值ai .同时 ...
- 「NOI2018」屠龙勇士 解题报告
「NOI2018」屠龙勇士 首先对于每个龙用哪个剑砍,我们可以用set随便模拟一下得到. 然后求出拿这个剑砍这条龙的答案 \[ atk_ix-p_iy=a_i \] 其中\(atk_i\)是砍第\(i ...
- 「NOI2018」屠龙勇士(CRT)
/* 首先杀每条龙用到的刀是能够确定的, 然后我们便得到了许多形如 ai - x * atki | pi的方程 而且限制了x的最小值 那么exgcd解出来就好了 之后就是扩展crt合并了 因为全T调了 ...
- LOJ 2721 「NOI2018」屠龙勇士——扩展中国剩余定理
题目:https://loj.ac/problem/2721 1.注意别一输入 p[ i ] 就 a[ i ] %= p[ i ] ,因为在 multiset 里找的时候还需要真实值. 2.注意用 m ...
- POJ1061 青蛙的约会 —— 扩展gcd
题目链接:https://vjudge.net/problem/POJ-1061 青蛙的约会 Time Limit: 1000MS Memory Limit: 10000K Total Submi ...
- 「NOI2018」你的名字
「NOI2018」你的名字 题目描述 小A 被选为了\(ION2018\) 的出题人,他精心准备了一道质量十分高的题目,且已经 把除了题目命名以外的工作都做好了. 由于\(ION\) 已经举办了很多届 ...
随机推荐
- js实现table内 某列的内容进行即时筛选
往往有些时候,我们把数据从数据库读取出来,显示到table里面,而此时来了个新需求,要在一个搜索框内输入关键字,表格的内容进行即时的筛选. 而即时触发进行数据库的查询,再回调显示,就显得慢,拖累服务器 ...
- ASP.NET MVC + ADO.NET EF 项目实战(一):应用程序布局设计
什么叫上下文? 在你设计一个方法的时候,无法直接从方法参数或实例成员(字段或属性)获得的所有信息都是上下文.例如: 当前用户是谁? 刚才提供操作的数据库连接实例从哪里拿到? 这个方法从哪个 View ...
- JAVA NIO 简介 (netty源码死磕1.1)
[基础篇]netty 源码死磕1.1: JAVA NIO简介 1. JAVA NIO简介 Java 中 New I/O类库 是由 Java 1.4 引进的异步 IO.由于之前老的I/O类库是阻塞I/ ...
- CSS 布局实例系列(三)如何实现一个左右宽度固定,中间自适应的三列布局——也聊聊双飞翼
今天聊聊一个经典的布局实例: 实现一个三列布局,其中左侧和右侧的部分宽度固定,中间部分宽度随浏览器宽度的变化而自适应变化 可能很多朋友已经笑了,这玩意儿通过双飞翼布局就能轻松实现.不过,还请容我在双飞 ...
- Android开发之深入理解泛型extends和super的区别
摘要: 什么是泛型?什么是擦除边界?什么是上界限定或下界限定(子类型限定或超类型限定)?什么是类型安全?泛型extends关和super关键字结合通配符?使用的区别,两种泛型在实际Android开发中 ...
- CentOS7安装MySQL8.0小计
之前讲配置文件和权限的时候有很多MySQL8的知识,有同志说安装不太一样,希望发个文,我这边简单演示一下 1.环境安装 下载MySQL提供的CentOS7的yum源 官方文档:<https:// ...
- Hadoop初体验
1.首先准备环境 系统:Linux(centOS) jdk:1.7 这里jdk要安装配置完成,具体步骤参考:Linux环境下安装JDK 注意:本次没有配置免密登录,所以在启动和停止的时候回让你输入多次 ...
- 混沌相关blog+节选
<数字化定量分析:一致性获利法时间跨度的定量研究> http://blog.sina.com.cn/s/blog_82cf83d50101a41q.html —— 用60分 ...
- ThinkPHP中Widget的两种写法及调用
Widget扩展一般用于页面组件的扩展,在页面根据需要输出不同的内容,下面介绍一下ThinkPHP中Widget的两种写法及调用 写法一: ArticlWidget.class.php文件: clas ...
- PAT 天梯赛 L2-003. 月饼 【贪心】
题目链接 https://www.patest.cn/contests/gplt/L2-003 思路 用贪心思路 最后注意一下 总售价有可能是浮点数 AC代码 #include <cstdio& ...