青蛙的约会

Language:Default
青蛙的约会
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

输入只包括一行5个整数x,y,m,n,L,其中x≠y < 2000000000,0 < m、n < 2000000000,0 < L < 2100000000。

Output

输出碰面所需要的跳跃次数,如果永远不可能碰面则输出一行"Impossible"

Sample Input

1 2 3 4 5

Sample Output

4

Source

分析

设\(a=m-n,b=y-x\),那么要解决的方程是

\[ax\equiv b\ (\bmod l) \\
\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:
复制

2
3 3
3 5 7
4 6 10
7 3 9
1 9 1000
3 2
3 5 6
4 8 7
1 1 1
1 1
输出样例#1:
复制

59
-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」屠龙勇士的更多相关文章

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

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

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

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

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

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

  4. 「NOI2018」屠龙勇士

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

  5. 「NOI2018」屠龙勇士 解题报告

    「NOI2018」屠龙勇士 首先对于每个龙用哪个剑砍,我们可以用set随便模拟一下得到. 然后求出拿这个剑砍这条龙的答案 \[ atk_ix-p_iy=a_i \] 其中\(atk_i\)是砍第\(i ...

  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. POJ1061 青蛙的约会 —— 扩展gcd

    题目链接:https://vjudge.net/problem/POJ-1061 青蛙的约会 Time Limit: 1000MS   Memory Limit: 10000K Total Submi ...

  9. 「NOI2018」你的名字

    「NOI2018」你的名字 题目描述 小A 被选为了\(ION2018\) 的出题人,他精心准备了一道质量十分高的题目,且已经 把除了题目命名以外的工作都做好了. 由于\(ION\) 已经举办了很多届 ...

随机推荐

  1. RGBA与半透明背景

    概念 所谓RGBA颜色,就是RGB三原色加ALPHA.在给背景加入颜色的同一时候.提供透明度特性. 用法 background:rgba(90,90, 54, 0.5); 支持情况 Firefox 3 ...

  2. 基于SqlDependency的Asp.net数据缓存

    首先,确保目标数据库的is_broker_enabled已经enabled. SELECT name, is_broker_enabled FROM sys.databases 如果不是enabled ...

  3. D - Invitation Cards

    D - Invitation Cards Time Limit:8000MS     Memory Limit:262144KB     64bit IO Format:%lld & %llu ...

  4. The hidden layers are either convolutional, pooling or fully connected.

    https://en.wikipedia.org/wiki/Convolutional_neural_network Convolutional layers apply a convolution ...

  5. 如何将cordova导入Android studio,只需两步即可

    Cordova的技术交流新群 微信公众号:

  6. 获取comboBox里面的item使用的方法

    使用currentIndex()或者currentText() void Widget::calc() { int first = ui->firstLineEdit->text().to ...

  7. python3.7.1 内置函数

    python3.7.1 内置函数列表 内置函数 abs() delattr() hash() memoryview() set() all() dict() help() min() setattr( ...

  8. MySQL 创建索引(Create Index)的方法和语法结构及例子

    MySQL 创建索引(Create Index)的方法和语法结构及例子 MySQL 创建索引(Create Index)的方法和语法结构及例子   CREATE INDEX Syntax CREATE ...

  9. 搭建SSM项目时报错(org.springframework.jdbc.CannotGetJdbcConnectionException)

    严重: Servlet.service() for servlet [SpringMVC] in context with path [/ssm] threw exception [Request p ...

  10. zabbix实现mysql数据库的监控(二)

    上章我们把zabbix的服务端和客户端都部署完成了,本章接着进行两部分的设置: 1  添加对mysql数据库主机的监控 2  添加对mysql数据库的监控 一.对数据库服务器主机监控 1 创建主机 步 ...