1.给出序列A,求序列B,使得bi|ai,lcm(b1,b2,...,bn)=lcm(a1,a2,...,an)且字典序最小。

可以发现,对于某个质数p,它有一个最大的次数k,将pk放在尽可能靠后且能够整除原数组中的数字的位置上,便是答案。

虽然数字的值域达到1E18,但我们只需要知道每个数1~1E6之间的质因子是什么以及是哪些,剩下来的一定是大于1E6的质因子且最多只有两个。

由于答案中的质数及其次数彼此间相互独立,1E6以下的质因子可以直接统计,而剩下的可以通过两两间求gcd的方法进行比较。在这种情况下,数字A和B(A在原数组的前面,B在后面)由于质数次数最多为2,令x=gcd(A,B),B除以x后(对于某个质因子)要么次数为0,要么为1,要么为2(2要特判一下,如果有这种情况,B要更新当且仅当A==B),乘上gcd(x,B除以x后)后即可进行更新。复杂度为O(n2*logMAX+MAX0.333)。

当然,若不嫌麻烦的话可套用pollard-rho模板。复杂度为O(n*MAX0.25)。

博主在考场上采用了后者。

 #include <cstdio>
#include <sstream>
#include <iostream>
#include <algorithm> using namespace std; typedef long long LL; const int MAXN = ; LL num[MAXN];
LL common[MAXN];
int n, cs; LL gcd(LL a, LL b)
{
LL tmp;
while (b) tmp = a, a = b, b = tmp % b;
return a;
} void solve()
{
for (int i = ; i < n; i++){
cs = ;
for (int j = ; j < n; j++)
if (i != j)
common[cs ++] = gcd(num[i], num[j]);
LL s = ;
for (int j = ; j < cs; j++){
s *= common[j];
for (int k = j+; k < cs; k++)
common[k] /= gcd(common[j], common[k]);
}
num[i] /= s;
while (true){
LL x = gcd(num[i], s);
if (x == )
break;
num[i] *= x;
s /= x;
}
}
} int main()
{
freopen("transform.in", "r", stdin);
freopen("transform.out", "w", stdout);
scanf("%d", &n);
for (int i = ; i < n; i ++)
scanf("%lld", &num[i]);
solve();
for (int i = ; i < n; i ++)
printf("%lld ", num[i]);
printf("\n");
return ;
}
 #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double ld;
ll n,a[],ans[];
map<ll,ll>cnt,where;
namespace math
{
const int len=;
ll test[len]={,,,,,,,,,};
ll size,wait[];
inline ll mul(ll x,ll y,ll mod)
{
ll d=(ld)x*y/mod;
return ((x*y-d*mod)%mod+mod)%mod;
}
inline ll QPOW(ll x,ll y)
{
ll ans=;
for(int i=;i<=y;++i)
ans=ans*x;
return ans;
}
inline ll qpow(ll x,ll y,ll mod)
{
ll ans=,base=x;
while(y)
{
if(y&)
ans=mul(ans,base,mod);
base=mul(base,base,mod);
y>>=;
}
return ans;
}
inline bool isPrime(ll p)
{
for(int i=;i<len;++i)
{
if(p<test[i])
return false;
else if(p==test[i])
return true;
ll x=qpow(test[i],p-,p),d=p-;
if(x!=)
return false;
while(x==&&d%==)
{
d>>=;
x=qpow(test[i],d,p);
if(x!=&&x!=p-)
return false;
}
}
return true;
}
ll gcd(ll x,ll y)
{
if(y==)
return x;
return x%y==?y:gcd(y,x%y);
}
inline ll f(ll x,int c,ll mod)
{
return (mul(x,x,mod)+c)%mod;
}
inline ll find(ll n,int step,int c)
{
if(n%==)
return ;
ll x=,y=,d=;
while(true)
{
ll tmpX=x,tmpY=y,d=;
for(int i=;i<=step;++i)
{
x=f(x,c,n);
y=f(f(y,c,n),c,n);
d=mul(d,(x%n-y%n+n)%n,n);
}
d=gcd(d,n);
if(d==)
continue;
else if(d!=n)
return d;
x=tmpX,y=tmpY;
for(int i=;i<=step;++i)
{
x=f(x,c,n);
y=f(f(y,c,n),c,n);
d=gcd(n,(x%n-y%n+n)%n);
if(d!=&&d!=n)
return d;
}
return ;
}
return -;
}
void factor(ll x)
{
if(isPrime(x))
{
wait[++size]=x;
return;
}
ll step=pow(x,0.1)+,c=,now=;
while(!now)
now=find(x,step,++c);
factor(now),factor(x/now);
}
void pollard(ll x,int num)
{
size=;
factor(x);
map<ll,ll>G;
// for(int i=1;i<=size;++i)
// cout<<wait[i]<<" ";
// cout<<endl;
for(int i=;i<=size;++i)
++G[wait[i]];
for(int i=;i<=size;++i)
{
x=wait[i];
if(G[x]>=cnt[x])
{
ans[where[x]]/=QPOW(x,cnt[x]);
cnt[x]=G[x];
where[x]=num;
ans[num]*=QPOW(x,cnt[x]);
}
}
}
}
inline bool check(int x)
{
if(x==)
return false;
for(int i=;i*i<=x;++i)
if(x%i==)
return false;
return true;
}
int main()
{
freopen("transform.in","r",stdin);
freopen("transform.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
for(int i=;i<=n;++i)
{
cin>>a[i];
ans[i]=;
math::pollard(a[i],i);
}
for(int i=;i<=n;++i)
cout<<ans[i]<<" ";
cout<<endl;
return ;
}

2.有一些机场和航线,航线是形如点A到点B的直线,飞机会准时从t1出发t2到达,期间匀速直线运动。机场和飞机都配备雷达,雷达有固定范围R,你需要保证在任意时间内,任意在飞行中的飞机能够通过雷达直接或间接地与机场相连,求最小的R。

  我们先二分半径r,考虑怎么进行检验。可以发现,不管是飞机关于机场、飞机关于飞机,它们能相互建立连接的可行时间点组成了一个区间,因此一个想法为求出这个区间,对于特定的端点建图进行检查。

对于飞机关于机场的情况是简单的。根据普通的平面向量知识,可以轻松地求出这个向量(飞机的飞行路线)与圆(圆心机场,半径为r)的两个交点(如果存在的话)。再次利用数量积的知识,可以知道这两个点到出发点的距离,与整个路线长度的比值(当然,这是有方向的)。求完后分别取min、max保证时间确实在航班时间范围内即可(比如说起点在圆里面的情况)。

飞机关于飞机比较麻烦。首先,我们先使得航线A和航线B的速度相等,这样方便下面求解。具体地讲,A向量的模除以时间A的值,要等于B向量的模除以时间的值。然后以飞机A为参考系,飞机B的航线路线就变为B-A。剩下的操作与“飞机关于机场”的完全一致,只不过要保证时间要在两个航班时间范围内。

还有一点要注意的是,向量可能经过圆心,这需要判断。

总共有O((n+m)2)个区间,单次建边、检查的复杂度是O((n+m)2)的,因此总复杂度为O((n+m)4logn)。

 #include<bits/stdc++.h>
using namespace std;
typedef long double ld;
const ld eps=1E-;
const ld inf=1E12;
int n,m;
int A[],B[];
ld from[],to[],length[];
struct pt
{
ld x,y;
pt(ld a=,ld b=):x(a),y(b){}
pt operator+(const pt&A){return pt(x+A.x,y+A.y);}
pt operator-(const pt&A){return pt(x-A.x,y-A.y);}
pt operator*(const ld&d){return pt(x*d,y*d);}
pt operator/(const ld&d){return pt(x/d,y/d);}
ld operator*(const pt&A){return x*A.y-y*A.x;}
ld operator&(const pt&A){return x*A.x+y*A.y;}
void out()
{
cout<<"("<<x<<","<<y<<")";
}
}p[];
struct line
{
pt A,B;
line(pt a=pt(),pt b=pt()):A(a),B(b){}
};
struct info
{
ld L,R;
int x,y;
info(ld a=,ld b=,int c=,int d=):L(a),R(b),x(c),y(d){}
}tmp[];
inline ld s(ld x){return x*x;}
inline pt intersection(line a,line b)
{
pt A=b.B-b.A,B=a.B-a.A,C=b.A-a.A;
if(abs(A*B)<=eps)
return pt(inf,inf);
ld d=-(B*C)/(B*A);
return b.A+A*d;
}
inline pt T(pt A)
{
return pt(-A.y,A.x);
}
inline pt perpendicular(pt A,line a)
{
if(abs((A-a.A)*(A-a.B))<=eps)
return A;
pt B=A+T(a.B-a.A);
return intersection(line(A,B),a);
}
inline ld dis(pt A,pt B)
{
return sqrt(s(A.x-B.x)+s(A.y-B.y));
}
namespace graph
{
int size,head[];
bool vis[];
struct edge
{
int to,next;
}E[];
inline void clear()
{
for(int i=;i<=n+m;++i)
head[i]=;
for(int i=;i<=size;++i)
E[i].to=E[i].next=;
size=;
}
inline void add(int u,int v)
{
E[++size].to=v;
E[size].next=head[u];
head[u]=size;
}
inline bool ok(ld x)
{
for(int i=;i<=n+m;++i)
vis[i]=;
queue<int>Q;
for(int i=;i<=n;++i)
{
Q.push(i);
vis[i]=;
}
while(!Q.empty())
{
int u=Q.front();
Q.pop();
for(int i=head[u];i;i=E[i].next)
{
int v=E[i].to;
if(vis[v])
continue;
Q.push(v);
vis[v]=;
}
}
for(int i=n+;i<=n+m;++i)
if((!vis[i])&&(from[i-n]-eps<=x&&x<=to[i-n]+eps))
return false;
return true;
}
}
int tot;
inline bool test(ld x)
{
graph::clear();
for(int i=;i<=tot;++i)
if(tmp[i].L-eps<=x&&x<=tmp[i].R+eps)
{
graph::add(tmp[i].x,tmp[i].y);
graph::add(tmp[i].y,tmp[i].x);
}
return graph::ok(x);
}
inline bool check(ld r)
{
tot=;
for(int i=;i<=n;++i)
{
pt O=p[i];
for(int j=;j<=m;++j)
{
line a(p[A[j]],p[B[j]]);
pt P=perpendicular(O,a),D,pA,pB;
ld d=s(P.x-O.x)+s(P.y-O.y);
if(d>r*r-eps)
continue;
else if(abs(d)<=eps)
D=(a.B-a.A)*r/dis(a.A,a.B);
else
D=T((P-O)*sqrt(r*r/d-));
pA=P+D,pB=P-D;
ld t1=((pA-p[A[j]])&(p[B[j]]-p[A[j]]))/length[j]/length[j]*(to[j]-from[j])+from[j];
ld t2=((pB-p[A[j]])&(p[B[j]]-p[A[j]]))/length[j]/length[j]*(to[j]-from[j])+from[j];
if(t1>t2)
swap(t1,t2);
t1=max(from[j],t1);
t2=min(to[j],t2);
if(t2-t1>=eps)
tmp[++tot]=info(t1,t2,i,n+j);
}
}
for(int i=;i<=m;++i)
for(int j=;j<=m;++j)
{
if(from[i]<=from[j])
continue;
ld delT=from[i]-from[j];
ld g=(ld)(to[i]-from[i])/(ld)(to[j]-from[j]-delT);
pt I=p[A[i]]-p[B[i]];
pt J=(p[B[j]]-p[A[j]])*delT/(to[j]-from[j]);
line a(p[A[j]]+J,p[A[j]]+J+I+(p[B[j]]-(p[A[j]]+J))*g);
pt O=p[A[i]];
pt P=perpendicular(O,a),D,pA,pB;
ld d=s(P.x-O.x)+s(P.y-O.y);
if(d>r*r-eps)
continue;
else if(abs(d)<=eps)
D=(a.B-a.A)*r/dis(a.A,a.B);
else
D=T((P-O)*sqrt(r*r/d-));
pA=P+D,pB=P-D;
ld len=dis(a.A,a.B);
ld t1=((pA-a.A)&(a.B-a.A))/len/len*(to[i]-from[i])+from[i];
ld t2=((pB-a.A)&(a.B-a.A))/len/len*(to[i]-from[i])+from[i];
if(t1>t2)
swap(t1,t2);
t1=max(max(from[i],from[j]),t1);
t2=min(min(to[i],to[j]),t2);
if(t2-t1>=eps)
tmp[++tot]=info(t1,t2,n+i,n+j);
}
for(int i=;i<=tot;++i)
{
if((!test(tmp[i].L-*eps))||(!test(tmp[i].R-*eps)))
return false;
if((!test(tmp[i].L+*eps))||(!test(tmp[i].R+*eps)))
return false;
}
return true;
}
int main()
{
freopen("airline.in","r",stdin);
freopen("airline.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=;i<=n;++i)
cin>>p[i].x>>p[i].y;
for(int i=;i<=m;++i)
{
cin>>A[i]>>B[i]>>from[i]>>to[i];
++A[i],++B[i];
}
for(int i=;i<=m;++i)
length[i]=dis(p[A[i]],p[B[i]]);
ld L=,R=,mid;
for(int i=;i<=n;++i)
for(int j=i+;j<=n;++j)
R=max(R,dis(p[i],p[j]));
R*=;
while(abs(R-L)>0.000001)
{
mid=(L+R)/;
if(check(mid))
R=mid;
else
L=mid;
}
cout<<fixed<<setprecision()<<mid<<endl;
return ;
}

我们先

二分半径r,考虑怎么进行检验。可以发现,不管是飞机关于机场、飞机关于飞机,它们能相互建立连接的可行时间点组成了一个区间,因此一个想法为求出这个区间,对于特定的端点建图进行检查。

对于飞机关于机场的情况是简单的。根据普通的平面向量知识,可以轻松地求出这个向量(飞机的飞行路线)与圆(圆心机场,半径为r)的两个交点(如果存在的话)。再次利用数量积的知识,可以知道这两个点到出发点的距离,与整个路线长度的比值(当然,这是有方向的)。求完后分别取min、max保证时间确实在航班时间范围内即可(比如说起点在圆里面的情况)。

飞机关于飞机比较麻烦。首先,我们先使得航线A和航线B的速度相等,这样方便下面求解。具体地讲,A向量的模除以时间A的值,要等于B向量的模除以时间的值。然后以飞机A为参考系,飞机B的航线路线就变为B-A。剩下的操作与“飞机关于机场”的完全一致,只不过要保证时间要在两个航班时间范围内。

还有一点要注意的是,向量可能经过圆心,这需要判断。

总共有O((n+m)2)个区间,单次建边、检查的复杂度是O((n+m)2)的,因此总复杂度为O((n+m)4logn)。

[校内训练20_01_22]ABC的更多相关文章

  1. [校内训练20_01_20]ABC

    1.问有多少个大小为N的无标号无根树,直径恰好为L.$N,L \leq 200$ 2.问一个竞赛图中有多少个长度为3.4.5的环.$N \leq 2000$ 3.给出一些直线和单个点A,问这些直线的交 ...

  2. [校内训练20_01_19]ABC

    1.SB题 2.有n个点,m条边,每次加入一条边,你要挑出一些边,使得形成的图每个点度数都为奇数,且最长的边最短. 3.给一个N次多项式,问有多少个质数在任意整数处的点值都是p的倍数,输出它们.$N ...

  3. [校内训练20_01_17]ABC

    1.平面上每次加入直角边平行于坐标轴的等腰直角三角形,每次询问某个点被覆盖了多少次. 大常数算法:O(nlog^2) #include<bits/stdc++.h> using names ...

  4. [4.14校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. hzwer又出丧题虐人 4道noi....        很奇怪 每次黄学长出题总有一题我做过了. 嗯题目你们自己看看呗 好难解释 ----- ...

  5. [2017.4.7校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. 报警啦.......hzwer又出丧题虐人啦..... 4道ctsc...有一道前几天做过了,一道傻逼哈希还wa了十几次,勉强过了3题..我好 ...

  6. [3.24校内训练赛by hzwer]

    来自FallDream的博客,未经允许,请勿转载,谢谢. ----------------------------------------------------------------------- ...

  7. 19_04_19校内训练[Game]

    题意 给出n,等概率地生成一个1~n的数列.现在有n个人从左到右站成一排,每个人拿有当前数列位置上的数字,并且一开始都不知道数字是多少(但知道n是多少).从左到右让每个人进行如下选择: 1.选择保留自 ...

  8. 19_04_02校内训练[deadline]

    题意 给出一个二分图,左边为A集合,右边为B集合,要求把A集合中每一个点染为黑白两色中的一种,B集合中的颜色已定.染色后对于原本相邻且颜色相同的点,建立新的二分图,即得到了两个新的二分图,它们是独立的 ...

  9. 平面图转对偶图&19_03_21校内训练 [Everfeel]

    对于每个平面图,都有唯一一个对偶图与之对应.若G‘是平面图G的对偶图,则满足: G'中每一条边的两个节点对应着G中有公共边的面,包括最外部无限大的面. 直观地讲,红色标出来的图就是蓝色标出的图的对偶图 ...

随机推荐

  1. geoip ip2region2 with spark

    上一篇文章中 我使用 maxmind的免费库开发了一个waterdrop的 插件,测试数据发现,国内的有些市级还是不准确,而且香港并不是显示中国,这就不友好了. 找了一下,发下 ip2region 这 ...

  2. docker 命令汇总1

    命令汇总 docker history fa5fa5为镜像id或者镜像名 docker export 30b >h.tar30b为容器id或者容器名# docker export angry_b ...

  3. 使用exp/imp 在oracle数据库间导数据

    最近工作需要将oracle数据库的表数据导出到另一个oracle数据库表,找到了oracle 自带的命令行,并记录下导数据过程. 导数据过程分以下几步: 假设源数据库为A,目标数据库为B 1.在B上通 ...

  4. Percona-XtraDB-Cluster 5.7版本(PXC)集群部署

    PXC(Percona-XtraDB-Cluster)5.7版本集群部署 Centos 7.3系统部署Mysql 集群 PXC三个节点分别执行和安装(1)配置hosts cat /etc/hosts1 ...

  5. 20191010-7 alpha week 1/2 Scrum立会报告+燃尽图 06

    此作业参见:https://edu.cnblogs.com/campus/nenu/2019fall/homework/8750 小组名称:“组长”组 组长:杨天宇 组员:魏新,罗杨美慧,王歆瑶,徐丽 ...

  6. 1061 判断题 (15 分)C语言

    判断题的评判很简单,本题就要求你写个简单的程序帮助老师判题并统计学生们判断题的得分. 输入格式: 输入在第一行给出两个不超过 100 的正整数 N 和 M,分别是学生人数和判断题数量.第二行给出 M ...

  7. 《深入理解JAVA虚拟机》-自己动手编译JDK

    环境 Ubuntu12.4-http://mirrors.163.com/ubuntu-releases/12.04/ --需要安装纯英文版,避免中文引起不必要的麻烦 OpenJDK7-https:/ ...

  8. keuectl命令

    Kubernetes命令行 kubectl用于运行Kubernetes集群命令的管理工具 kubectl命令行语法 kubectl [command] [TYPE] [NAME] [flags] co ...

  9. Leetcode1296划分数组为连续数字的集合

    解法1: 最暴力的方法,存每个数字出现的次数,排序之后,扫一遍,对于每个数字,看它后面连续的k-1个是否都存在. 耗时:404ms class Solution { public: bool isPo ...

  10. 【tf.keras】使用手册

    目录 0. 简介 1. 安装 1.1 安装 CUDA 和 cuDNN 2. 数据集 2.1 使用 tensorflow_datasets 导入公共数据集 2.2 数据集过大导致内存溢出 2.3 加载 ...