ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF653G Move by Prime 题解

2021-11-14 20:33:42  阅读:188  来源: 互联网

标签:Prime dbinom int 题解 sum Move 中位数 read void


Codeforces
Luogu

Description.

定义 \(F(S)\) 为把 \(S\) 中每次可以把每个元素 \(\times p,\div p(p\in\text{prime})\) 把所有元素变相同的最少步数。
求 \(\sum_{T\subseteq S}F(T)\)。

Solution.

质因数可以拆开,分别求解
对于每个质因数,有一个序列表示指数
现在相当于对所有子序列求到中位数差之和
可以考虑枚举中位数为 \(m\)(定义中位数偏左
然后相当于要求 \(\sum|X-m|\) 其中 \(m\) 是中位数。
绝对值拆开后,\(m\) 的贡献肯定是 \(0\)。
相当于在左边选 \(a\) 个,右边选 \(b\) 个的贡献是下式:

\[\begin{cases} -X&a<b\\ 0&a=b\\ X&a>b\\ \end{cases} \]

可以枚举 \(b-a+i-1\),意义是左边不选个数和右边选个数之和。
因为 \(i\) 当前确定,左边不选、右边选总方案数就相当于从 \(n-1\) 里选出这些数,方案数是 \(\dbinom{n-1}{b-a+i-1}\)。
则有贡献为

\[\begin{aligned} &=X\left(\sum_{j=0}^{i-2}\dbinom{n-1}{j}-\sum_{j=i}^{n-1}\dbinom{n-1}{j}\right)\\ &=X\left(2^{n-1}-2\sum_{j=i-1}^{n-1}\dbinom{n-1}{j}+\dbinom{n-1}{i}\right)\\ \end{aligned} \]

然后预处理组合数前缀和就做完了。

Coding.

点击查看代码
//Coded by Kamiyama_Shiki on 2021.11.14 {{{
//是啊……你就是那只鬼了……所以被你碰到以后,就轮到我变成鬼了
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
	x=0;char c=getchar(),f=0;
	for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
	for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	f?x=-x:x;
}
template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
const int N=300005,P=1000000007;
namespace Binom//{{{
{
	int fc[N],fi[N],iv[N];//dbinit
	inline int ksm(int x,int q=P-2) {int r=1;for(;q;q>>=1,x=1ll*x*x%P) if(q&1) r=1ll*r*x%P;return r;}
	inline void dbinit(int n=N-1)
	{
		fc[0]=1;for(int i=1;i<=n;i++) fc[i]=1ll*fc[i-1]*i%P;
		iv[1]=1;for(int i=2;i<=n;i++) iv[i]=1ll*iv[P%i]*(P-P/i)%P;
		fi[0]=1;for(int i=1;i<=n;i++) fi[i]=1ll*fi[i-1]*iv[i]%P;
	}
	inline int C(int n,int m) {return n<0||m<0||n<m?0:1ll*fc[n]*fi[m]%P*fi[n-m]%P;}
}using Binom::dbinit;using Binom::C;using Binom::ksm;//}}}
const int V=N;int pr[V],pc,ls[V];char pv[V];//prinit{{{
inline void prinit(int n=V-1)
{
	pv[1]=1,ls[1]=0;for(int i=1;i<=n;i++)
	{
		if(!pv[i]) pr[++pc]=i,ls[i]=i;
		for(int j=1;j<=pc&&i*pr[j]<=n;j++) {pv[i*pr[j]]=1,ls[i*pr[j]]=pr[j];if(i%pr[j]==0) break;}
	}
}//}}}
int n,a[N],c[N],qz[N],rs=0;vector<int>fc[N];
int main()
{
	read(n),prinit(),dbinit();for(int i=1;i<=n;i++) read(a[i]);
	int pw=ksm(2,n-1);for(int i=n-1;~i;i--) qz[i]=(qz[i+1]+(c[i]=C(n-1,i)))%P;
	for(int i=1,x=a[i];i<=n;x=a[++i]) while(ls[x]) {int v=ls[x],c=0;while(x%v==0) x/=v,c++;fc[v].push_back(c);}
	for(int i=1;i<N;i++) if(!fc[i].empty())
	{
		sort(fc[i].begin(),fc[i].end());int cnt=n-fc[i].size();
		//printf("%d\n",i);for(int j:fc[i]) printf("%d ",j);putchar('\n');
		for(int j=0;j<(int)fc[i].size();j++) rs=(rs+1ll*fc[i][j]*(pw-2ll*qz[cnt+j]%P+P+c[cnt+j]))%P;
		//for(int j=0;j<(int)fc[i].size();j++) printf("gg %d - %lld + %d\n",pw,2ll*qz[cnt+j]%P,c[cnt+j]);
	}return printf("%d\n",rs),0;
}

标签:Prime,dbinom,int,题解,sum,Move,中位数,read,void
来源: https://www.cnblogs.com/pealfrog/p/15553166.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有