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. c3p0连接池封装

    在处理数据库事物时需要同一个Connection  但是dbcp无法获得  单独工具也显得繁琐,改进成c3p0工具类: package utils; import java.sql.Connectio ...

  2. Avram Joel Spolsky给计算机系学生的建议

    Avram Joel Spolsky给计算机系的学生给了如下建议:     (1)毕业前练好写作     (2)毕业前学好C语言     (3)毕业前学好微观经济学     (4)不要因为枯燥就不选修 ...

  3. C语言中的关键字总结

    1.auto 修饰局部变量,编译器默认所有局部变量都是用auto来修饰的,所以在程序中很少见到. 2.static 它作用可大了,除了可以修饰变量,还可以修饰函数,修饰变量,改变其作用域和生命周期,修 ...

  4. 24.configparser&hashlib

    转载:https://www.cnblogs.com/yuanchenqi/article/5732581.html configparser 来看一个好多软件的常见文档格式如下: [DEFAULT] ...

  5. 使用 Git和Github

    本地库初始化 git init 效果: 注意: .git 目录中存放的是本地库相关的子目录和文件,不要删除,也不要胡 乱修改. 设置签名 其实就是为了区分不同开发人员的身份需要设置一下自己的信息,包括 ...

  6. 利用python第三方库提取PDF文件的表格内容

    小爬最近接到一个棘手任务:需要提取手机话费电子发票PDF文件中的数据.接到这个任务的第一时间,小爬决定搜集各个地区各个时间段的电子发票文件,看看其中的差异点.粗略统计下来,PDF文件的表格框架是统一的 ...

  7. 【题解】BZOJ4548 小奇的糖果(树状数组)

    [题解]BZOJ4548 小奇的糖果(树状数组) 说在前面:我有个同学叫小奇,他有一个朋友叫达达,达达特爱地理和旅游,初中经常AK地理,好怀恋和他已经达达一起到当时初中附近许多楼盘的顶楼逛的时光... ...

  8. $CF888E\ Maximum\ Subsequence$ 搜索

    正解:$meet\ in\ the\ middle$ 解题报告: 传送门$QwQ$. 发现数据范围为$n\leq 35$,所以$2^{\frac{n}{2}}$是可做的. 所以先拆成$A,B$两个集合 ...

  9. 洛谷$P3749$ [六省联考2017] 寿司餐厅 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 这道题好烦昂,,,就给了好多变量,,,但仔细读一遍题还是能$get$的所以我就不再提取一遍题目大意辣$QwQ$? 显然考虑建两排点,一排收益一排支出然后最小 ...

  10. Hive直接读取Hbase及MySQL数据

    0.概述 Hive对外提供了StorageHandler接口,提供了访问各种存储组件中的数据的能力.Hbase提供了HbaseStorageHandler,使得hive可以通过建立外部映射表访问hba ...