Codeforces 870F - Path(数论+分类讨论+正难则反)
首先考虑 \(d(u,v)\) 是个什么东西,分情况讨论:
- \(u\not\perp v\),\(d(u,v)=1\)
- \(u\perp v\),记 \(p_u\) 为 \(u\) 的最小质因子,\(p_v\) 为 \(v\) 的最小质因子,那么继续分情况讨论:
- \(p_up_v\le n\),\(d(u,v)=2\)(\(u\to p_up_v\to v\))
- \(p_up_v>n\) 且 \(\max(p_u,p_v)\le\dfrac{n}{2}\),\(d(u,v)=3\)(\(u\to 2p_u\to 2p_v\to v\))
- \(p_up_v>n\) 且 \(\max(p_u,p_v)>\dfrac{n}{2}\),\(d(u,v)=0\)
考虑对这四种情况分别计算,对于 \(d(u,v)=1\) 显然预处理出欧拉函数即可处理,即 \(\dbinom{n-1}{2}-\sum\limits_{i=1}^n(\varphi(i)-1)\)(由于 \(1\) 不能与任何点连边,因此 \(d(u,v)\ne 0\) 的点只可能在另外 \(n-1\) 个点之间),对于 \(d(u,v)=2\) 的情况直接处理比较困难,因此考虑正难则反,拿总方案数减去另外三种情况的方案数即可计算,对于第三种情况,由于 \(p_up_v>0\),因此在 \([1,n]\) 中不存在某个数既是 \(p_u\) 也是 \(p_v\) 的倍数,因此对于某个固定的 \(p_u,p_v\),合法的 \(u,v\) 的对数即是 \([1,n]\) 中 \(p_x=p_u\) 的 \(x\) 的个数与 \([1,n]\) 中 \(p_x=p_v\) 的 \(x\) 的个数之积。我们不妨假设 \(p_u<p_v\),我们记 \(cnt_x\) 表示 \([1,n]\) 中有多少个数最小质因子为 \(x\),那么考虑枚举 \(p_u\),合法的 \(p_v\) 必然在区间 \((\max(p_u,\dfrac{n}{p_u}),\dfrac{n}{2}]\) 之间,前缀和优化一下即可。对于第四种情况也同理,枚举 \(p_u\),合法的 \(p_v\) 在区间 \((\max(i,\dfrac{n}{2}),n]\) 之间。第二种情况减一下即可,复杂度线性。
最后讲一下我翻车的现场,我是考虑求出分别求出 \(d(u,v)=1/2/3\) 的情况并将它们的贡献加起来,\(d(u,v)=1,3\) 的情况自然是很容易求得的,但是 \(d(u,v)=2\) 的情况不好计算,然后我就一直在分析如何计算这种情况的方案数,xtbz……看来以后对于计算方案数的问题,如果正面计算比较困难要学会正难则反,学到了学到了(
const int MAXN=1e7;
int n,pr[MAXN/10+5],prcnt=0,mnp[MAXN+5],phi[MAXN+5],cnt[MAXN+5];
bitset<MAXN+5> vis;
void sieve(){
phi[1]=1;
for(int i=2;i<=n;i++){
if(!vis.test(i)){pr[++prcnt]=i;phi[i]=i-1;mnp[i]=i;}
for(int j=1;pr[j]*i<=n&&j<=prcnt;j++){
vis[pr[j]*i]=1;mnp[pr[j]*i]=pr[j];
if(i%pr[j]==0){phi[pr[j]*i]=phi[i]*pr[j];break;}
else phi[pr[j]*i]=phi[i]*phi[pr[j]];
}
}
}
int calc(int l,int r){return (l>r)?0:(cnt[r]-cnt[l]);}
int main(){
scanf("%d",&n);sieve();ll sum=0,ans0=0,ans1=0,ans2=0,ans3=0;
for(int i=2;i<=n;i++) cnt[mnp[i]]++;
for(int i=1;i<=n;i++) cnt[i]+=cnt[i-1];
for(int i=1;i<=n;i++) sum+=phi[i]-1;
ans1=1ll*(n-1)*(n-2)/2-sum;
for(int i=1;i<=n;i++){
int num=cnt[i]-cnt[i-1];
if(i<=n/2) ans3+=1ll*num*calc(max(i,n/i),n/2);
ans0+=1ll*num*calc(max(n/2,i),n);
} ans2=sum-ans0-ans3;
printf("%lld\n",ans1+(ans2<<1)+(ans3<<1)+ans3);
return 0;
}
Codeforces 870F - Path(数论+分类讨论+正难则反)的更多相关文章
- FZU 2122 又见LKity【字符串/正难则反/KMP/把一个字符串中某个部分替换为另一个部分】
嗨!大家好,在TempleRun中大家都认识我了吧.我是又笨又穷的猫猫LKity.很高兴这次又与各位FZU的ACMer见面了.最近见到FZU的各位ACMer都在刻苦地集训,整天在日光浴中闲得发慌的我压 ...
- P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反)
P1197 [JSOI2008]星球大战(并查集判断连通块+正难则反) 并查集本来就是连一对不同父亲的节点就的话连通块就少一个. 题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统 ...
- Educational Codeforces Round 74 (Rated for Div. 2)【A,B,C【贪心】,D【正难则反的思想】】
A. Prime Subtractiontime limit per test2 secondsmemory limit per test256 megabytesinputstandard inpu ...
- Codeforces.520B.Two Buttons(正难则反)
题目链接 \(Description\) 给定两个数\(n,m\),每次可以使\(n\)减一或使\(n\)乘2.求最少需要多少次可以使\(n\)等于\(m\). \(Solution\) 暴力连边BF ...
- CodeForces 788B - Weird journey [ 分类讨论 ] [ 欧拉通路 ]
题意: 给出无向图. good way : 仅有两条边只经过一次,余下边全经过两次的路 问你共有多少条不同的good way. 两条good way不同仅当它们所经过的边的集合中至少有一条不同 (很关 ...
- Codeforces Round #189 (Div. 2) A. Magic Numbers【正难则反/给出一个数字串判断是否只由1,14和144组成】
A. Magic Numbers time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- CF 1005B Delete from the Left 【模拟数组操作/正难则反】
You are given two strings s and t. In a single move, you can choose any of two strings and delete th ...
- 树上统计treecnt(dsu on tree 并查集 正难则反)
题目链接 dalao们怎么都写的线段树合并啊.. dsu跑的好慢. \(Description\) 给定一棵\(n(n\leq 10^5)\)个点的树. 定义\(Tree[L,R]\)表示为了使得\( ...
- 洛谷 P1049 装箱问题【正难则反/01背包】
题目描述 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30,每个物品有一个体积(正整数). 要求n个物品中,任取若干个装入箱内,使箱子的剩余 ...
随机推荐
- 封装一个的toast弹出框(vue项目)
逆风的方向,更适合飞翔 实现效果 实现步骤 先写出一个toast组件 // Toast.vue <template> <div id="toast" :class ...
- BUAA_2020_软件工程_结对项目作业
项目 内容 这个作业属于哪个课程 班级博客 这个作业的要求在哪里 作业要求 我在这个课程的目标是 掌握软件工程的思路方法 这个作业在哪个具体方面帮助我实现目标 学习结对编程 教学班级 006 项目地址 ...
- Java基础之原生JDBC操作数据库
前言 日常开发中,我们都习惯了使用ORM框架来帮我们操作数据库,本文复习.记录Java如何使用原生JDBC操作数据库 代码编写 封装几个简单方法 find查询方法 findOne查询方法 update ...
- STM32中按键中断分析
在按键学习中,我们有用到查询的方法来判断按键事件是否发生,这种查询按键事件适用于程序工作量较少的情况下,一旦程序中工作量较大较多,则势必影响程序运行的效率,为了简化程序中控制的功能模块的执行时间,引入 ...
- 最长子序列(线性DP)学习笔记
子序列和子串不一样.子串要求必须连续,而子序列不需要连续. 比如说\(\{a_1,a_2\dots a_n\}\),他的子串就是\(\{a_i,a_{i+1},\dots, a_j|1\leq i\l ...
- 运用Tomcat创建第一个web项目
一.了解Web服务器软件 在部署tomcat前,先说一说web服务器软件是用来干什么的?简单来说,就是web容器,可以部署web项目,让用户通过浏览器来访问这些项目. 1.常见的javaweb服务器软 ...
- 单源最短路径算法:迪杰斯特拉 (Dijkstra) 算法(一)
一.算法介绍 迪杰斯特拉算法(英语:Dijkstra's algorithm)由荷兰计算机科学家艾兹赫尔·迪杰斯特拉在1956年提出.迪杰斯特拉算法使用了广度优先搜索解决赋权有向图的单源最短路径问题. ...
- nod_1009 数字1的数量(分析题)
题意: 给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数. 例如:n = 12,包含了5个1.1,10,12共包含3个1,11包含2个1,总共5个1. Input 输入 ...
- Navicat15 For Mysql最新版完美破解图文教程(支持Win和Mac)
Navicat15 For Mysql最新版完美破解 欢迎关注博主公众号[跟着Mic学架构],专注于分享Java领域技术干货,回复关键字 [面试资料] 可以获得海量面试资料. 申明,本教程 Navic ...
- linux初中级命令语言
Linux:开源免费.大部分软件都可以自由获取,同样功能的软件选择较少.主要是字符模式,命令行界面且发行版本较多,难以集中攻击. Xshell与xftp是什么? xshell是一个客户端软件,我们本地 ...