「NOI2018」屠龙勇士 解题报告
「NOI2018」屠龙勇士
首先对于每个龙用哪个剑砍,我们可以用set随便模拟一下得到。
然后求出拿这个剑砍这条龙的答案
\]
其中\(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:
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <set>
#define ll long long
using std::max;
const int SIZE=1<<21;
char ibuf[SIZE],*iS,*iT;
#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),iS==iT?EOF:*iS++):*iS++)
//#define gc() getchar()
template <class T>
void read(T &x)
{
	x=0;char c=gc();
	while(!isdigit(c)) c=gc();
	while(isdigit(c)) x=x*10+c-'0',c=gc();
}
std::multiset <ll> s;
std::multiset <ll>::iterator it;
const int N=1e5+10;
int n,m;
ll hp[N],p[N],atk[N],A[N],B[N];
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void exgcd(ll a,ll b,ll &x,ll &y)
{
	if(!b)
	{
		x=1,y=0;
		return;
	}
	exgcd(b,a%b,x,y);
	ll tmp=x;
	x=y;
	y=tmp-a/b*y;
}
ll mul(ll d,ll k,ll p)
{
    ll f=0;
    while(k)
    {
        if(k&1) (f+=d)%=p;
        (d+=d)%=p;
        k>>=1;
    }
    return f;
}
void work()
{
    ll mx=0;
	s.clear();
	read(n),read(m);
	for(int i=1;i<=n;i++) read(hp[i]);
	for(int i=1;i<=n;i++) read(p[i]);
	for(int i=1;i<=n;i++) read(atk[i]);
	for(int i=1;i<=m;i++)
	{
		ll x;
		read(x);
		s.insert(x);
	}
	for(int i=1;i<=n;i++)
	{
		ll a,b,c,x,y;
		it=s.upper_bound(hp[i]);
		if(it==s.begin())
		{
			b=*it;
			s.erase(it);
		}
		else
		{
			it--;
			b=*it;
			s.erase(it);
		}
		a=b,b=p[i],c=hp[i];
		ll d=gcd(a,b);
		if(c%d!=0)
		{
			puts("-1");
			return;
		}
        mx=max(mx,(c-1)/a+1);
		exgcd(a,b,x,y);
		x=mul(x,c/d,b/d);
		x=(x%(b/d)+b/d)%(b/d);
		A[i]=x,B[i]=b/d;
		s.insert(atk[i]);
	}
	for(int i=2;i<=n;i++)
	{
		if(A[i]==A[i-1])
		{
			B[i]=B[i]/gcd(B[i],B[i-1])*B[i-1];
			continue;
		}
		if(A[i]<A[i-1]) std::swap(A[i],A[i-1]),std::swap(B[i],B[i-1]);
		ll a=B[i-1],b=B[i],c=A[i]-A[i-1],d=gcd(a,b),x,y;
		if(c%d!=0)
		{
			puts("-1");
			return;
		}
		exgcd(a,b,x,y);
		x=mul(x,c/d,b/d);
		B[i]=a/d*b;
		A[i]=((A[i-1]+mul(x,B[i-1],B[i]))%B[i]+B[i])%B[i];
	}
	printf("%lld\n",max(A[n],mx));
}
int main()
{
    freopen("dragon.in","r",stdin);
    freopen("dragon.out","w",stdout);
	int T;read(T);
	while(T--) work();
	return 0;
}
2019.4.30
「NOI2018」屠龙勇士 解题报告的更多相关文章
- 「NOI2018」屠龙勇士
		
「NOI2018」屠龙勇士 题目描述 小\(D\)最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照编号\(1-n\)顺序杀掉\(n\) 条巨龙,每条巨龙拥有一个初始的生命 值ai .同时 ...
 - 「NOI2018」屠龙勇士(EXCRT)
		
「NOI2018」屠龙勇士(EXCRT) 终于把传说中 \(NOI2018D2\) 的签到题写掉了... 开始我还没读懂题目...而且这题细节巨麻烦...(可能对我而言) 首先我们要转换一下,每次的 ...
 - LOJ #2721. 「NOI2018」屠龙勇士(set + exgcd)
		
题意 LOJ #2721. 「NOI2018」屠龙勇士 题解 首先假设每条龙都可以打死,每次拿到的剑攻击力为 \(ATK\) . 这个需要支持每次插入一个数,查找比一个 \(\le\) 数最大的数(或 ...
 - loj#2721. 「NOI2018」屠龙勇士
		
题目链接 loj#2721. 「NOI2018」屠龙勇士 题解 首先可以列出线性方程组 方程组转化为在模p意义下的同余方程 因为不保证pp 互素,考虑扩展中国剩余定理合并 方程组是带系数的,我们要做的 ...
 - POJ1061 青蛙的约会 和 LOJ2721 「NOI2018」屠龙勇士
		
青蛙的约会 Language:Default 青蛙的约会 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 133470 Accep ...
 - 「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 ...
 - 「FJOI2016」神秘数 解题报告
		
「FJOI2016」神秘数 这题不sb,我挺sb的... 我连不带区间的都不会哇 考虑给你一个整数集,如何求这个神秘数 这有点像一个01背包,复杂度和值域有关.但是你发现01背包可以求出更多的东西,就 ...
 - 「ZJOI2016」大森林 解题报告
		
「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...
 
随机推荐
- HTML5+CSS3特效设计集锦
			
20款CSS3鼠标经过文字背景动画特效 站长之家 -- HTML5特效索引 爱果果h5酷站欣赏 30个酷毙的交互式网站(HTML5+CSS3) 轻松搞定动画!17个有趣实用的CSS 3悬停效果教程 ...
 - Windows-WAMP搭建与配置
			
使用 WampServer 整合软件包进行 WAMP 环境搭建 WampServer 是一款由法国人开发的 Apache Web 服务器.PHP 解释器以及 MySQL 数据库的整合软件包.免去了开发 ...
 - 71、salesforce的JSON方法
			
List<Merchandise__c> merchandise = [select Id,Name,Price__c,Quantity__c from Merchandise__c li ...
 - WebGPU学习(九):学习“fractalCube”示例
			
大家好,本文学习Chrome->webgpu-samplers->fractalCube示例. 上一篇博文: WebGPU学习(八):学习"texturedCube"示 ...
 - LInux终端中Ctrl+S卡死
			
因为初学Linux,在vim中写东西是总是喜欢按Ctrl+s来保存内容导致终端突然卡主,然后上网查资料发现了Ctrl+s 暂停屏幕输出[锁住终端]而对应的按键是Ctrl+q 恢复屏幕输出[解锁终端]
 - 数据分析系列篇:玩转excel
			
数据分析系列篇:玩转excel 不知道现在怎么也变得这么鸡婆,连excel都要准备写一篇.没办法,还有很多不是做数据的小伙伴们不会excel啊,抱着不抛弃.不放弃的态度,就讲下excel如何玩转.其实 ...
 - 在dos中编译java文件
			
首先Dos中 编译java文件是:javac (所有)类名.java 运行java文件是:java 包名.类名 java指令默认在寻找class文件的地址是通过CLASSPATH环境变量中指定的目录中 ...
 - 2019牛客多校第⑨场E All men are brothers(并查集+组合数学)
			
原题:https://ac.nowcoder.com/acm/contest/889/E 思路: 做并查集,维护每个集合大小,初始化操作前的总方案数,每次合并两个集合时减少的数量=合并的两个集合大小相 ...
 - Linux下JDK1.6升级1.8版本
			
先不管是否已安装JDK1.6还是JDK1.7,先下载 jdk-8u45-linux-x64.rpm 然后上传到 /usr/local/src 去.当然其他目录也可以.这里是默认位置 给所有用户 ...
 - Linux部分常用命令详解(一)
			
echo 命令详解 格式: echo string 显示普通字符: echo "it is a test" 或者 echo it is a test 显示转义字符: echo &q ...