题目描述

牛牛在纸上画了\(N\)个点(从\(1\)到\(N\)编号),每个点的颜色用一个整数描述。

牛牛决定用这\(N\)个点随机生成一棵树,生成的规则如下:

  1. \(1\)号点是根节点
  2. 对于\(2\)号点到\(N\)号点,每个点随机指定一个父亲。\(i\)号点(\(2 \leq i \leq N)\)的父亲在i的约数中随机挑选一个。(例如\(10\)号点的父亲可以是\(1\)号,\(2\)号,\(5\)号,\(7\)号点的父亲只能是\(1\)号点)树生成完之后,牛牛可以计算出这个树有多少个联通块,一个联通块是一些点的集合,需要满足以下两个条件:
    • 从集合中任取两个点都满足:两个点颜色相同,且这两个点之间存在一条树边组成的路径,路径上的所有点都和这两个点颜色相同
    • 对于集合中的任意一个点和集合外的任意一个点:两点要么不同色,要么不存在一条树边组成的路径使得路径上所有点都和这两个点同色。

牛牛希望计算出生成的树中最多有多少个联通块

输入描述:

第一行一个整数\(N\)代表点数

第二行\(N\)个整数,第\(i\)个整数\(c_i\)代表第\(i\)个点的颜色

对于\(30\%\)的数据, \(2 \leq N \leq 10\), \(颜色1 \leq \text{颜色} \leq 5\)

对于\(60\%\)的数据, \(2 \leq N \leq 5000\),$颜色1 \leq \text{颜色} \leq $5000

对于\(80\%\)的数据, \(2 \leq N \leq 200000\), \(颜色1 \leq \text{颜色} \leq 10^9\)

对于\(100\%\)的数据, \(2 \leq N \leq 500000\), \(颜色1 \leq \text{颜色} \leq 10^9\)

输出描述:

输出一个整数最多有多少联通块

示例1

输入

4
1 1 1 2

输出

2

说明

\(2\)号点和\(3\)号点的父亲一定是\(1\),\(4\)号点父亲可能是\(1\)或者\(2\),两种情况下联通块数都是\(2\)

Solution

通过打暴力时候的一个操作发现解法。

我们发现,一个点的颜色只要与其父节点不同,那么联通块就会多一个,否则不变。

因此,我们只需要对于一个数,枚举其所有可行的父节点 ,只要颜色不一样就可以加。

然而这样是\(O(n^2)\)的。

这里有一个技巧:我们化枚举因数为枚举倍数。

for(int i=1;i<=n;++i)
for(int j=i+i;j<=n;j+=i);

这个东西的时间复杂度为\(O(n\log n)\)

因为这个东西需要执行的次数为

\[\frac n1+\frac n2+\frac n3+...+\frac nn=n(\frac11+\frac12+\frac13+...+\frac1n)=n(\ln(n+1)+r)
\]

其中\(r\)为欧拉常数,近似值为$0.5772156649 $。

#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#define lowbit(x) ((x)&(-(x)))
#define REP(i,a,n) for(register int i=(a);i<=(n);++i)
#define PER(i,a,n) for(register int i=(a);i>=(n);--i)
#define FEC(i,x) for(register int i=head[x];i;i=g[i].ne)
#define dbg(...) fprintf(stderr,__VA_ARGS__)
namespace io{
const int SIZE=(1<<21)+1;char ibuf[SIZE],*iS,*iT,obuf[SIZE],*oS=obuf,*oT=oS+SIZE-1,c,qu[55];int f,qr;
#define gc() (iS==iT?(iT=(iS=ibuf)+fread(ibuf,1,SIZE,stdin),(iS==iT?EOF:*iS++)):*iS++)
inline void flush(){fwrite(obuf,1,oS-obuf,stdout);oS=obuf;}
inline void putc(char x){*oS++=x;if(oS==oT)flush();}
template<class I>inline void read(I &x){for(f=1,c=gc();c<'0'||c>'9';c=gc())if(c=='-')f=-1;for(x=0;c<='9'&&c>='0';c=gc())x=x*10+(c&15);x*=f;}
template<class I>inline void write(I x){if(!x)putc('0');if(x<0)putc('-'),x=-x;while(x)qu[++qr]=x%10+'0',x/=10;while(qr)putc(qu[qr--]);}
inline void print(const char *s){while(*s!='\0')putc(*s++);}
inline void scan(char *s){for(c=gc();c<=' ';c=gc());for(;c>' ';c=gc())*(s++)=c;*s='\0';}
struct Flusher_{~Flusher_(){flush();}}io_flusher_;
}//orz laofudasuan
using io::read;using io::putc;using io::write;using io::print;
typedef long long ll;typedef unsigned long long ull;
template<typename A,typename B>inline bool SMAX(A&x,const B&y){return x<y?x=y,1:0;}
template<typename A,typename B>inline bool SMIN(A&x,const B&y){return y<x?x=y,1:0;} const int N=500000+7;
int n,a[N],ans=1,fst[N]; int main(){
#ifndef ONLINE_JUDGE
freopen("B.in","r",stdin);freopen("B.out","w",stdout);
#endif
read(n);for(register int i=1;i<=n;++i)read(a[i]);
for(register int i=1;i<=n;++i)
for(register int j=i+i;j<=n;j+=i)
SMAX(fst[j],a[i]!=a[j]);
for(register int i=2;i<=n;++i)ans+=fst[i];
write(ans),putc('\n');
}

牛客网NOIP赛前集训营-提高组(第七场)B-随机生成树的更多相关文章

  1. 牛客网NOIP赛前集训营-普及组(第二场)和 牛客网NOIP赛前集训营-提高组(第二场)解题报告

    目录 牛客网NOIP赛前集训营-普及组(第二场) A 你好诶加币 B 最后一次 C 选择颜色 D 合法括号序列 牛客网NOIP赛前集训营-提高组(第二场) A 方差 B 分糖果 C 集合划分 牛客网N ...

  2. 牛客网NOIP赛前集训营-提高组(第二场)A 方差

    链接:https://www.nowcoder.com/acm/contest/173/A来源:牛客网 题目描述 一个长度为 m 的序列 b[1...m] ,我们定义它的方差为 ,其中  表示序列的平 ...

  3. [牛客网NOIP赛前集训营-提高组(第一场)]C.保护

    链接:https://www.nowcoder.com/acm/contest/172/C来源:牛客网 题目描述 C国有n个城市,城市间通过一个树形结构形成一个连通图.城市编号为1到n,其中1号城市为 ...

  4. 牛客网NOIP赛前集训营-提高组(第一场)

    牛客的这场比赛感觉真心不错!! 打得还是很过瘾的.水平也比较适合. T1:中位数: 题目描述 小N得到了一个非常神奇的序列A.这个序列长度为N,下标从1开始.A的一个子区间对应一个序列,可以由数对[l ...

  5. 比赛总结——牛客网 NOIP赛前集训营提高组模拟第一场

    第一场打的很惨淡啊 t1二分+前缀最小值没想出来,20分的暴力也挂了,只有10分 t2数位dp,调了半天,结果因为忘了判0的特殊情况WA了一个点,亏死 t3emmmm.. 不会 imone说是DSU ...

  6. 牛客网NOIP赛前集训营-提高组(第一场)B 数数字

    数数字 思路: 数位dp 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include< ...

  7. 牛客网NOIP赛前集训营-提高组(第一场)A 中位数

    中位数 思路: 二分答案 代码: #pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include< ...

  8. 牛客网NOIP赛前集训营 提高组 第5场 T2 旅游

    [题解] 我们可以发现不在最小生成树上的边一定不能多次经过,因为一条不在最小生成树上的边(u,v)的边权比最小生成树上(u,v)之间的路径更长,选择不在最小生成树上的边一定不划算. 我们还需要确定最小 ...

  9. 牛客网NOIP赛前集训营-提高组(第四场)游记

    牛客网NOIP赛前集训营-提高组(第四场)游记 动态点分治 题目大意: \(T(t\le10000)\)组询问,求\([l,r]\)中\(k(l,r,k<2^{63})\)的非负整数次幂的数的个 ...

  10. 牛客网NOIP赛前集训营-提高组(第四场)B区间

    牛客网NOIP赛前集训营-提高组(第四场)B区间 题目描述 给出一个序列$ a_1  \dots   a_n$. 定义一个区间 \([l,r]\) 是好的,当且仅当这个区间中存在一个 \(i\),使得 ...

随机推荐

  1. 请问有支持直接从 word 文档复制图片的 editor 吗

    Chrome+IE默认支持粘贴剪切板中的图片,但是我要发布的文章存在word里面,图片多达数十张,我总不能一张一张复制吧?Chrome高版本提供了可以将单张图片转换在BASE64字符串的功能.但是无法 ...

  2. docker运行spring boot 包镜像出现no main manifest attribute问题

    问题: 在进行docker部署的时候,开始对项目进行打包,在启动该镜像时 [root@topcheer docker]# docker run -it 00494e3d4550no main mani ...

  3. Elven Postman

    Elven Postman Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  4. Oracle中动态SQL详解(EXECUTE IMMEDIATE)

    Oracle中动态SQL详解(EXECUTE IMMEDIATE) 2017年05月02日 18:35:48 悠悠倾我心 阅读数:744 标签: oracle动态sqloracle 更多 个人分类:  ...

  5. scrapy--meta参数传递问题

    scrapy使用大坑---meta参数传递出现之重复问题 问题描述: 爬虫目标: 实现哔哩哔哩网站的视频信息爬取,只要的信息结构爬去顺序为**关键词的搜索结果,拿到第一页上某个视频的标题,url,和时 ...

  6. mysqladmin - 管理 MySQL 服务器、获取运行状态

    官方文档 mysqladmin 是管理 MySQL 服务器的客户端,可以用来检测服务器的配置和当前状态.创建和删除数据库等. 1. mysqladmin 的调用语法 shell> mysqlad ...

  7. 16/7/27-PHP环境配置(php5.5.3.7+mysql5.7.12+Apache2.4)

    非常感谢http://www.cnblogs.com/jicheng1014/archive/2012/01/26/2329531.html 配置php环境问题 php.ini 路径 "\& ...

  8. 简单入门爬斗鱼颜值区妹子照片 v1.1

    这是个比较简单的入门爬虫.基于python3. urllib,urllib2,python3中用urllib.request代替,使用方法基本一致. #python3 import urllib.re ...

  9. NYOJ 654喜欢玩warcraft的ltl(01背包/常数级优化)

    传送门 Description ltl 非常喜欢玩warcraft,因为warcraft十分讲究团队整体实力,而他自己现在也为升级而不拖累团队而努力. 他现在有很多个地点来选择去刷怪升级,但是在每一个 ...

  10. .apk的MIME类型

    1.扩展名: .apk      MIME类型: application/vnd.android 2.Internet 服务管理器添加.apk:打开IIS --->找到MIME类型,双击之 -- ...