[POI2012]Odległość

题目大意:

一个长度为\(n(n\le10^5)\)的序列\(A(1\le A_i\le10^6)\),定义\(d(i,j)\)为每次对\(A_i,A_j\)中的一个数乘一个质数\(p\),让\(A_i=A_j\)的最少操作步数。

对于每个\(i\),求能使\(d(i,j)\)最小的\(j\),若有多个解,输出最小的\(j\)。

思路:

用\(f(x)\)表示\(x\)所有质因子次数之和,则\(d(i,j)=f(A_i)+f(A_j)-2f(\gcd(A_i,A_j))\)。

对于每个\(A_i\),枚举其约数作为\(\gcd\),对于每个约数记录其倍数\(x\)中最小、次小的\(f(x)\)。

时间复杂度\(\mathcal O(n\sqrt m)\)。

这样能在BZOJ通过,但是不能在SZKOpuł上通过。官方题解提供的做法是\(\mathcal O(n\log\log n)\)。

源代码:

#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=1e5+1,A=1e6+1;
int a[N],d[A],p[A];
bool vis[A];
std::pair<int,int> min[A][2];
inline void sieve(const int &n) {
for(register int i=2;i<=n;i++) {
if(!vis[i]) {
d[i]=1;
p[++p[0]]=i;
}
for(register int j=1;p[j]*i<=n;j++) {
vis[p[j]*i]=true;
d[p[j]*i]=d[i]+1;
if(i%p[j]==0) break;
}
}
}
inline void upd(const int &j,const int &i) {
std::pair<int,int> tmp=std::make_pair(d[a[i]]-d[j]*2,i);
if(tmp<min[j][0]) std::swap(tmp,min[j][0]);
if(tmp<min[j][1]) std::swap(tmp,min[j][1]);
}
int main() {
const int n=getint();
for(register int i=1;i<=n;i++) {
a[i]=getint();
}
const int m=*std::max_element(&a[1],&a[n]+1);
sieve(m);
for(register int i=1;i<=m;i++) {
min[i][0]=min[i][1]=std::make_pair(INT_MAX,INT_MAX);
}
for(register int i=1;i<=n;i++) {
for(register int j=1;j*j<=a[i];j++) {
if(a[i]%j) continue;
upd(j,i);
if(j*j!=a[i]) upd(a[i]/j,i);
}
}
for(register int i=1;i<=n;i++) {
std::pair<int,int> ans=std::make_pair(INT_MAX,INT_MAX);
for(register int j=1;j*j<=a[i];j++) {
if(a[i]%j) continue;
ans=std::min(ans,min[j][min[j][0].second==i]);
ans=std::min(ans,min[a[i]/j][min[a[i]/j][0].second==i]);
}
printf("%d\n",ans.second);
}
return 0;
}

[POI2012]Odległość的更多相关文章

  1. 2795: [Poi2012]A Horrible Poem

    2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 484  Solved: 235[Subm ...

  2. [BZOJ2803][Poi2012]Prefixuffix

    2803: [Poi2012]Prefixuffix Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 219  Solved: 95[Submit][St ...

  3. [BZOJ2799][Poi2012]Salaries

    2799: [Poi2012]Salaries Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 91  Solved: 54[Submit][Statu ...

  4. [BZOJ2797][Poi2012]Squarks

    2797: [Poi2012]Squarks Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 211  Solved: 89[Submit][Status ...

  5. [BZOJ2791][Poi2012]Rendezvous

    2791: [Poi2012]Rendezvous Time Limit: 25 Sec  Memory Limit: 128 MBSubmit: 95  Solved: 71[Submit][Sta ...

  6. [BZOJ2795][Poi2012]A Horrible Poem

    2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 261  Solved: 150[Subm ...

  7. [BZOJ2794][Poi2012]Cloakroom

    2794: [Poi2012]Cloakroom Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 167  Solved: 119[Submit][St ...

  8. [BZOJ2793][Poi2012]Vouchers

    2793: [Poi2012]Vouchers Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 316  Solved: 148[Submit][Stat ...

  9. [BZOJ2792][Poi2012]Well

    2792: [Poi2012]Well Time Limit: 40 Sec  Memory Limit: 64 MBSubmit: 137  Solved: 61[Submit][Status][D ...

随机推荐

  1. Node.js模块化教程

    Node.js模块化教程 下载安装node.js 创建项目结构 |-modules |-module1.js |-module2.js |-module3.js|-app.js|-package.js ...

  2. Java转换流、缓冲流、流操作规律整理

    转换流 1.1                OutputStreamWriter类 OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的字符编码表,将要写入流中的字符编码成字 ...

  3. Python动态语言的特性

    一.动态语言相关概念 1.1 动态语言 在运行时代码可以根据某些条件改变自身结构 可以在运行时引进新的函数.对象.甚至代码,可以删除已有的函数等其他结构上的变化 常见的动态语言:Object-C.C# ...

  4. Docker:常用命令大全 [七]

    一.docker的命令的解释 1.命令解释 docker run -d -p 80:80 nginx run (创建并运行一个容器) -d 放在后台 -p 端口映射 nginx docker镜像的名字 ...

  5. MySQL的一些基本命令笔记(4)

    delete 语句嵌套子查询: delete from 表名1 where 列名 操作符 (select 列名 from 表名2 where 条件); 示例: delete from customer ...

  6. Educational Codeforces Round 52 (Rated for Div. 2)

    题目链接 A. Vasya and Chocolate 题意 已知钱,价格,赠送规则求最多获得巧克力数 思路常规算即可 代码 #include <bits/stdc++.h> #defin ...

  7. css和css3弹性盒模型实现元素宽度(高度)自适应

    一.css实现左侧宽度固定右侧宽度自适应 1.定位 <!DOCTYPE html> <html lang="en"> <head> <me ...

  8. Leetcode#70. Climbing Stairs(爬楼梯)

    题目描述 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: 输入: 2 输出: 2 解 ...

  9. Kotlin 检查空类型

    Kotlin 会检查你定义的非空类型 如果运行过程中被赋空值了  会直接crash

  10. 51nod 1016 水仙花数

    大水仙花数模板+1…… #include<stdio.h> #include<math.h> #include<queue> #include<vector& ...