这是拓展crt的典型应用

在你开始做之前,我一定要告诉你一件事情:虽然这道题看着和拓展crt模板很像,但他俩是有巨大的区别的!不要直接把板子改吧改吧扔上去!

题目模型:求解模线性方程组

其中p1,p2...pn不一定互质

第一眼:拓展crt板子题!

第二眼:等等...好像不太对

第三眼:WTF!系数哪来的!

我们知道,拓展crt的模板只能解决x系数为1的情况,而系数不为1的是很难做的!

什么?直接乘逆元变成1?

逆元不存在呢?

我们稍微做一点推导:

首先,我们解一下方程

设这个方程的一个解是x0(这是可以使用拓展gcd求解的)

那么这个方程的通解应该是,k∈Z

那么这个通解等价于方程的解

发现什么了吗?

是的!我们证明了方程与方程等价,这样就消掉了前面那个方程的系数!

所以,原方程组等价于这样:

这就很好了,我们使用正常的拓展crt解之即可

最后有几个细节问题:

①:对于ai>pi的情况,题目中给出的约束条件是pi=1,这样虽然拓展crt处理不了,但是我们可以应用特判过掉(p=1啊,多显然)

②:对于所有ai=pi的情况(即任一ai都=pi),只有当对应的攻击力是pi的倍数的时候才有解,否则无解,这个也要特判(有解也要特判,否则拓展crt解的结果会是0)

③:对于部分ai=pi的情况,如果对应攻击力不是pi的倍数则无解,但如果是pi的倍数,那么这个方程基本没用,可以替换成之类的形式

④:题目中运算很大,对于带取模的乘法需要快速加优化!同时所有数据类型建议使用long long以免挂掉

(求前驱那里本人使用的是treap,表示很好用)

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ll long long
#define ls tree[rt].lson
#define rs tree[rt].rson
#define INF 0x3f3f3f3f
using namespace std;
ll n,m;
ll a[];
ll b[];
ll life[];
ll acc[];
ll p[];
ll s[];
int cyt=;
int rot=;
struct Treap
{
int lson;
int rson;
int huge;
int same;
ll val;
int rank;
}tree[];
void update(int rt)
{
tree[rt].huge=tree[ls].huge+tree[rs].huge+tree[rt].same;
}
void lturn(int &rt)
{
int temp=rs;
rs=tree[rs].lson;
tree[temp].lson=rt;
tree[rt].huge=tree[temp].huge;
update(temp);
rt=temp;
}
void rturn(int &rt)
{
int temp=ls;
ls=tree[ls].rson;
tree[temp].rson=rt;
tree[rt].huge=tree[temp].huge;
update(temp);
rt=temp;
}
void ins(int &rt,ll v)
{
if(!rt)
{
rt=++cyt;
tree[rt].huge=;
tree[rt].same=;
tree[rt].val=v;
tree[rt].rank=rand();
return;
}
if(v==tree[rt].val)
{
tree[rt].huge++;
tree[rt].same++;
return;
}else if(tree[rt].val>v)
{
ins(ls,v);
if(tree[ls].rank<tree[rt].rank)
{
rturn(rt);
}
}else
{
ins(rs,v);
if(tree[rs].rank<tree[rt].rank)
{
lturn(rt);
}
}
}
void del(int &rt,ll v)
{
if(!rt)
{
return;
}
if(tree[rt].val==v)
{
if(tree[rt].same>)
{
tree[rt].huge--;
tree[rt].same--;
return;
}else if(ls*rs==)
{
rt=ls+rs;
return;
}else
{
if(tree[ls].rank<tree[rs].rank)
{
rturn(rt);
del(rt,v);
}else
{
lturn(rt);
del(rt,v);
}
}
}
tree[rt].huge--;
if(tree[rt].val>v)
{
del(ls,v);
}else
{
del(rs,v);
}
update(rt);
}
void query_pro(int rt,ll v,int typ)
{
if(!rt)
{
return;
}
if(tree[rt].val==v)
{
acc[typ]=v;
return;
}else if(tree[rt].val<v)
{
acc[typ]=tree[rt].val;
query_pro(rs,v,typ);
}else
{
query_pro(ls,v,typ);
}
}
int query_min(int rt)
{
if(ls&&tree[ls].val!=-INF)
{
return query_min(ls);
}else if(tree[rt].val!=-INF)
{
return tree[rt].val;
}else
{
return query_min(rs);
}
}
ll pow_add(ll x,ll y,ll mod)
{
ll ans=;
while(y)
{
if(y%)
{
ans+=x;
ans%=mod;
}
y/=;
x+=x;
x%=mod;
}
return ans;
}
ll gcd(ll x,ll y)
{
if(y==)
{
return x;
}
return gcd(y,x%y);
}
void ex_gcd(ll a,ll b,ll &x,ll &y)
{
if(b==)
{
x=;
y=;
return;
}
ex_gcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-(a/b)*x;
}
bool makeit()
{
for(int i=;i<=n;i++)
{
if(acc[i]%p[i]==)
{
if(p[i]==life[i])
{
a[i]=;
b[i]=;
continue;
}else
{
printf("-1\n");
return ;
}
}
ll x,y;
ll r=gcd(acc[i],p[i]);
if(life[i]%r)
{
printf("-1\n");
exit();
}
acc[i]/=r;
ll temp=life[i]/r;
ll tt=p[i]/r;
ex_gcd(acc[i],tt,x,y);
x=(pow_add(x,temp,tt)+tt)%tt;
b[i]=x;
a[i]=tt;
}
return ;
}
ll ex_crt()
{
ll M0=a[];
ll ans=b[];
for(int i=;i<=n;i++)
{
ll r=gcd(M0,a[i]);
ll bb=((b[i]-ans)%a[i]+a[i])%a[i];
if(bb%r)
{
return -;
}
bb/=r;
ll M=M0/r;
ll aa=a[i]/r;
ll x,y;
ex_gcd(M,aa,x,y);
x=pow_add(x,bb,aa);
ans+=x*M0;
M0*=aa;
ans=(ans%M0+M0)%M0;
}
return (ans%M0+M0)%M0;
}
ll T;
int main()
{
scanf("%lld",&T);
while(T--)
{
memset(tree,,sizeof(tree));
rot=;
cyt=;
ins(rot,-INF);
scanf("%lld%lld",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%lld",&life[i]);//龙的生命力
}
bool flag=,flag1=;
for(int i=;i<=n;i++)
{
scanf("%lld",&p[i]);//龙的恢复力
if(life[i]>p[i])
{
flag=;
}
if(life[i]!=p[i])
{
flag1=;
}
}
for(int i=;i<=n;i++)
{
scanf("%lld",&s[i]);
}
for(int i=;i<=m;i++)
{
ll x;
scanf("%lld",&x);
ins(rot,x);
}
for(int i=;i<=n;i++)
{
acc[i]=;
query_pro(rot,life[i],i);
if(acc[i]==-INF)
{
acc[i]=query_min(rot);
}
del(rot,acc[i]);
ins(rot,s[i]);
}
if(!flag1)
{
bool flag2=;
ll ans=;
for(int i=;i<=n;i++)
{
if(life[i]%acc[i]!=)
{
printf("-1\n");
flag2=;
}else
{
ll cd=gcd(ans,life[i]/acc[i]);
ans*=life[i]/acc[i]/cd;
}
}
if(!flag2)
{
printf("%lld\n",ans);
}
continue;
}
if(flag)
{
ll temp=;
for(int i=;i<=n;i++)
{
if(life[i]%acc[i]!=)
{
temp=max(temp,life[i]/acc[i]+);
}else
{
temp=max(temp,life[i]/acc[i]);
}
}
printf("%lld\n",temp);
continue;
}
if(makeit())
{
continue;
}
printf("%lld\n",ex_crt());
}
return ;
}

bzoj 5418的更多相关文章

  1. [LOJ 2721][UOJ 396][BZOJ 5418][NOI 2018]屠龙勇士

    [LOJ 2721][UOJ 396][BZOJ 5418][NOI 2018]屠龙勇士 题意 题面好啰嗦啊直接粘LOJ题面好了 小 D 最近在网上发现了一款小游戏.游戏的规则如下: 游戏的目标是按照 ...

  2. 【刷题】BZOJ 5418 [Noi2018]屠龙勇士

    www.lydsy.com/JudgeOnline/upload/noi2018day2.pdf Solution 将攻击的式子列出来,\(atk \times x-p \times y=a_i\) ...

  3. BZOJ 5418: [Noi2018]屠龙勇士 EXCRT+multiset

    题解:求解形如 $A[i]ans\equiv b[i](mod$ $p[i])$ 的 $x$ 的最小正整数解. 考虑只有一个等式,那么可以直接化成 $exgcd$ 的形式:$A[i]ans+p[i]y ...

  4. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  5. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  6. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  7. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  8. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  9. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

随机推荐

  1. c/C++编译的程序占用的内存分为以下几个部分

    首先要搞清楚编译程序占用的内存的分区形式:一.预备知识—程序的内存分配一个由c/C++编译的程序占用的内存分为以下几个部分1.栈区(stack)—由编译器自动分配释放,存放函数的参数值,局部变量的值等 ...

  2. neutron-----openstack网络操作

    #查看子网 openstack subnet list #删除子网 openstack subnet delete name/id #查看网络 openstack network list #删除网络 ...

  3. flask 连接数据库

    FLASK 连接mysql 数据库 1 # -*- encoding: utf-8 -*- 2 3 from flask import Flask 4 #导入第三方连接库 5 from flask_s ...

  4. webgl开发中添加IIS的mime类型

    1.在iis中直接设置 .obj application/octet-stream .mtl application/octet-stream 2.在配置文件中加 <?xml version=& ...

  5. HDOJ 1754 I Hate It (线段树)

    题目: Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感.不管你喜不喜欢,现在需要你做的是,就是按照老师的要 ...

  6. delphi 控件集

    delphi  控件集: 1)RAIZE 控件包  :http://www.raize.com/devtools/rzcomps/   被收购 Raize Components has been ac ...

  7. Chromium Embedded Framework (CEF)_3.2171.2069_v20170606_x86.tar.xz

    CEF 为观看各个直播平台而特此修改的浏览器 可以单独提取 Flash 视频, 并可以修改视频的大小等功能 [增加了960x90% 和 1280x90%] 这次修改是主要针对 YY web 直播平台 ...

  8. Vue 核心之数据劫持

    前端界空前繁荣,各种框架横空出世,包括各类mvvm框架横行霸道,比如Angular.Regular.Vue.React等等,它们最大的优点就是可以实现数据绑定,再也不需要手动进行DOM操作了,它们实现 ...

  9. Java文件复制

    主要是工作代码,无解释. /** * 将文件或文件夹source复制到dest * <br>目标文件检测: * <br> a.当文件不存在时:需要创建文件 * <br&g ...

  10. Spring4-@Enable** 注解的实现原理

    背景 在前面的工作中使用SpringBoot的时候,我碰到了很多的使用@Enable***注解的地方,使用上也都是加在@Configuration 类注解的类上面,比如: (1)@EnableAuto ...