「NOI2018」屠龙勇士(CRT)
/*
首先杀每条龙用到的刀是能够确定的, 然后我们便得到了许多形如 ai - x * atki | pi的方程
而且限制了x的最小值
那么exgcd解出来就好了
之后就是扩展crt合并了
因为全T调了一个小时 结果是没加文件??
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<set>
#include<iostream>
#define ll long long
#define M 100010
#define mmp make_pair
using namespace std;
ll read()
{
ll nm = 0, f = 1;
char c = getchar();
for(; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0';
return nm * f;
}
ll n, q, a[M], m[M], p[M], g[M], atk[M], tp, maxx;
multiset<ll> st;
ll mul(ll a, ll b, ll mod)
{
b = (b % mod + mod) % mod;
ll ans = 0, tmp = a;
for(; b; b >>= 1, tmp = (tmp + tmp) % mod) if(b & 1) ans = (ans + tmp) % mod;
return ans;
}
ll gcd(ll a, ll b)
{
return !b ? a : gcd(b, a % b);
}
ll exgcd(ll a, ll b, ll &x, ll &y)
{
if(!b)
{
x = 1, y = 0;
return a;
}
else
{
ll d = exgcd(b, a % b, x, y);
ll tmp = x;
x = y, y = tmp - a / b * y;
return d;
}
}
ll inv(ll a, ll p)
{
ll x, y;
ll d = exgcd(a, p, x, y);
if(d != 1) return -1;
return (x % p + p) % p;
}
void init()
{
st.clear();
tp = maxx = 0;
n = read(), q = read();
for(int i = 1; i <= n; i++) a[i] = read();
for(int i = 1; i <= n; i++) p[i] = read();
for(int i = 1; i <= n; i++) g[i] = read();
for(int i = 1; i <= q; i++) st.insert(read());
for(int i = 1; i <= n; i++)
{
multiset<ll>::iterator it = st.upper_bound(a[i]);
if(it != st.begin()) it--;
atk[i] = *it;
st.erase(it);
st.insert(g[i]);
}
}
ll excrt()
{
ll a1 = a[1], m1 = m[1], a2, m2;
if(tp == 0)
{
a1 = 0;
}
else
{
for(int i = 2; i <= tp; i++)
{
a2 = a[i], m2 = m[i];
ll d = gcd(m1, m2);
ll c = a2 - a1;
if(c % d) return -1;
ll k = inv(m1 / d, m2 / d);
m2 = m1 / d * m2;
a1 = mul(mul(m1 / d, c, m2), k, m2) + a1;
a1 %= m2;
m1 = m2;
}
}
return max(a1, maxx);
}
void cz(int i)
{
// a[i] - x * atk[i] + k * pi = 0
// a[i] = x * atk[i] - k * p[i]
// x * atk[i] = a[i] mod p[i]
//先处理gcd, 然后处理逆元
if(p[i] == 1)
{
maxx = max(maxx, (a[i] + atk[i] - 1) / atk[i]);
}
else
{
tp++;
ll gcdd = gcd(atk[i], p[i]);
if(a[i] % gcdd)
{
a[tp] = -1;
}
else
{
atk[i] /= gcdd, p[i] /= gcdd;
a[i] /= gcdd;
a[tp] = mul(a[i], inv(atk[i], p[i]), p[i]);
m[tp] = p[i];
}
}
}
void work()
{
for(int i = 1; i <= n; i++)
{
cz(i);
if(a[tp] == -1)
{
puts("-1");
return;
}
}
cout << excrt() << "\n";
}
int main()
{
freopen("dragon.in", "r", stdin);
freopen("dragon.out", "w", stdout);
//freopen("dragon1.in", "r", stdin);
int t = read();
while(t--)
{
init();
work();
}
return 0;
}
「NOI2018」屠龙勇士(CRT)的更多相关文章
- loj#2721. 「NOI2018」屠龙勇士
题目链接 loj#2721. 「NOI2018」屠龙勇士 题解 首先可以列出线性方程组 方程组转化为在模p意义下的同余方程 因为不保证pp 互素,考虑扩展中国剩余定理合并 方程组是带系数的,我们要做的 ...
- 「NOI2018」屠龙勇士
「NOI2018」屠龙勇士 题目描述 小\(D\)最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照编号\(1-n\)顺序杀掉\(n\) 条巨龙,每条巨龙拥有一个初始的生命 值ai .同时 ...
- 「NOI2018」屠龙勇士(EXCRT)
「NOI2018」屠龙勇士(EXCRT) 终于把传说中 \(NOI2018D2\) 的签到题写掉了... 开始我还没读懂题目...而且这题细节巨麻烦...(可能对我而言) 首先我们要转换一下,每次的 ...
- LOJ #2721. 「NOI2018」屠龙勇士(set + exgcd)
题意 LOJ #2721. 「NOI2018」屠龙勇士 题解 首先假设每条龙都可以打死,每次拿到的剑攻击力为 \(ATK\) . 这个需要支持每次插入一个数,查找比一个 \(\le\) 数最大的数(或 ...
- POJ1061 青蛙的约会 和 LOJ2721 「NOI2018」屠龙勇士
青蛙的约会 Language:Default 青蛙的约会 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 133470 Accep ...
- 「NOI2018」屠龙勇士 解题报告
「NOI2018」屠龙勇士 首先对于每个龙用哪个剑砍,我们可以用set随便模拟一下得到. 然后求出拿这个剑砍这条龙的答案 \[ atk_ix-p_iy=a_i \] 其中\(atk_i\)是砍第\(i ...
- LOJ 2721 「NOI2018」屠龙勇士——扩展中国剩余定理
题目:https://loj.ac/problem/2721 1.注意别一输入 p[ i ] 就 a[ i ] %= p[ i ] ,因为在 multiset 里找的时候还需要真实值. 2.注意用 m ...
- 【BZOJ5418】【NOI2018】屠龙勇士(数论,exgcd)
[NOI2018]屠龙勇士(数论,exgcd) 题面 洛谷 题解 考场上半个小时就会做了,一个小时就写完了.. 然后发现没过样例,结果大力调发现中间值爆\(longlong\)了,然后就没管了.. 然 ...
- 「NOI2018」你的名字
「NOI2018」你的名字 题目描述 小A 被选为了\(ION2018\) 的出题人,他精心准备了一道质量十分高的题目,且已经 把除了题目命名以外的工作都做好了. 由于\(ION\) 已经举办了很多届 ...
随机推荐
- docker 容器时间跟宿主机时间同步
docker 容器时间跟宿主机时间同步 docker cp /etc/localtime 87986863838b:/etc/docker cp /etc/localtime container-na ...
- Docker和Rancher
Docker打包流程: Dockerfile文件和要打包docker的文件放在同级目录下: 1. docker build -t proj:proj-app:0.0.1 返回tagXXX 2. doc ...
- WEB开发库收集
1. EASYUI http://www.jeasyui.com/ [INTRODUCTION] jQuery EasyUI framework helps you build yo ...
- py-day1-6 python 5个灰魔法 【len,index索引,for循环,切片】
# 索引,下标,获取字符串中的某一个字符. test = 'MuMingJun' v = test[3] print(v) i # 切片 test = 'MuMingJun' v = test[0:- ...
- Linux中chown和chmod的区别和用法
转载自:http://www.cnblogs.com/EasonJim/p/6525242.html chmod修改第一列内容,chown修改第3.4列内容: chown用法: 用来更改某个目录或文件 ...
- OpenWrt挂载移动硬盘实现脱机下载
一.编译选项选好好usb存储驱动,参考http://www.cnblogs.com/smbx-ztbz/p/4418245.html 并且选上kmod-usb-hid,用于usbhub. 二.编译选项 ...
- JAVA面试-java虚拟机
1.JVM简析: 作为一名Java使用者,掌握JVM的体系结构也是很有必要的. 说起Java,我们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Ja ...
- 写在vue总结之前(二)
都说要快速学会一个技术(会使用),比如一个框架,在实际的工作中做相关的项目是最快的学习方式.而为什么在实际的工作项目中去学习是最快的方式?个人的体会是,在实际的工作项目中,很多功能的实现是你不得不做的 ...
- HDOJ 2001 计算两点间的距离
#include<iostream> #include<cstdio> using namespace std; int main() { double a, b, x, y; ...
- 1125 Chain the Ropes (25 分)
1125 Chain the Ropes (25 分) Given some segments of rope, you are supposed to chain them into one rop ...