首页 > 其他分享 >BZOJ 4833 最小公倍佩尔数 题解 (数论,推式子)

BZOJ 4833 最小公倍佩尔数 题解 (数论,推式子)

时间:2022-12-02 15:14:55浏览次数:69  
标签:subset lcm gcd 题解 4833 公倍 cdots prod define

题目链接

神奇数论题。

做这题需要知道两个结论:

  • 对于满足\(f_{i+2}=a\cdot f_{i+1}+b\cdot f_{i}\),也就是形式类似斐波那契数列的序列,有\(gcd(f_i,f_j)=f_{gcd(i,j)}\)(据说是这样,我不确定正确性,但至少这题中a=2,b=1的情况是对的)
  • 对于一个集合\(S\)(可以是多重集),有\(lcm(S)=\prod_{T\subset S,|T|>0} gcd(T)^{(-1)^{|T|+1}}\)。其实就是min-max容斥,对于因数中的每一个质数分别考虑,lcm是取这个质数出现次数的最大值,gcd是取最小值,符合min-max容斥的形式。

先转化一下题意:有一个序列\(f\)满足\(f_{i+2}=2f_{i+1}+f_i,f_0=0,f_1=1\),令\(g_n=lcm(f_1,f_2\cdots f_n)\),求\(\sum_{i=1}^n g_i\cdot i\)对\(p\)取模的值。

套用上面两个结论的式子:

\[\begin{align} g_n&=lcm(f_1\cdots f_n)\\ &=\prod_{T\subset S,|T|>0} (gcd_{i\in T} f_i)^{(-1)^{|T|+1}}\ \ S表示\{1,2,\cdots n\}的集合,注意不是\{f_1\cdots f_n\}\\ &=\prod_{T\subset S,|T|>0} (f_{gcd(T)})^{(-1)^{|T|+1}}\\ \end{align} \]

\(f_n=\prod_{d|n}h_d\)。注意是\(\prod\)不是\(\sum\)。

用\(h\)进一步简化式子:

\[\begin{align} g_n&=\prod_{T\subset S,|T|>0} (f_{gcd(T)})^{(-1)^{|T|+1}}\\ &=\prod_{T\subset S,|T|>0}(\prod_{d|gcd(T)} h_d)^{(-1)^{|T|+1}}\\ &=\prod_{d=1}^n (h_d)^{\sum_{T\subset S,|T|>0} (-1)^{|T|+1}}\ \ 其中要求T中元素都是d倍数\\ &=\prod_{d=1}^n (h_d)^{\sum_{|T|>0} (-1)^{|T|+1}}\ \ 其中要求T中元素\le\frac nd\\ &=\prod_{d=1}^n h_d\ \ 注意到后面的幂次永远=1\\ \end{align} \]

这样,只要能求出序列\(h\),这题就做完了。\(h\)可以从前往后构造,枚举到\(i\)时,令\(h_i=\frac {f_i}{\prod_{d|i,d\ne i}h_d}\)。

总时间复杂度\(O(nlogn)\)。

点击查看代码
#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<n;++i)
#define repn(i,n) for(int i=1;i<=n;++i)
#define LL long long
#define pii pair <int,int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back

void fileio()
{
  #ifdef LGS
  freopen("in.txt","r",stdin);
  freopen("out.txt","w",stdout);
  #endif
}
void termin()
{
  #ifdef LGS
  std::cout<<"\n\nPROGRAM TERMINATED";
  #endif
  exit(0);
}

using namespace std;

LL t,n,p,f[1000010],h[1000010];
bool vis[1000010];

LL qpow(LL x,LL a)
{
  x%=p;if(x==0) return 0;
	LL res=x,ret=1;
	while(a>0)
	{
		if(a&1) (ret*=res)%=p;
		a>>=1;
		(res*=res)%=p;
	}
	return ret;
}

int main()
{
	fileio();

  cin>>t;
  rep(tn,t)
  {
    scanf("%lld%lld",&n,&p);
    f[1]=1;for(int i=2;i<=n+3;++i) f[i]=(f[i-1]+f[i-1]+f[i-2])%p;
    repn(i,n) h[i]=1;
    repn(i,n)
    {
      h[i]=f[i]*qpow(h[i],p-2)%p;
      for(LL j=i+i;j<=n;j+=i) (h[j]*=h[i])%=p;
    }
    LL ans=0;
    repn(i,n)
    {
      (h[i+1]*=h[i])%=p;
      (ans+=h[i]*i)%=p;
    }
    printf("%lld\n",ans);
  }

	termin();
}

标签:subset,lcm,gcd,题解,4833,公倍,cdots,prod,define
From: https://www.cnblogs.com/legendstane/p/bzoj-4833-solution.html

相关文章

  • 高通 QXDM5 安装后 打不开 问题解决
    QXDM5安装完成后,打开时显示找不到Qt5WebKit.dll文件,网上找了Qt5WebKit.dll等dll导入QXDM5目录,照样是失败,打不开程序,最终找到的解决方案如下:1.先卸载已安装的QXDM5和 Q......
  • shiro低版本更新到高版本(>1.10.0)出现报错问题解决
    近期漏洞爆出(ApacheShiro<1.10.0身份认证绕过漏洞),开始升级新版的jar包。升级过程1.修改pom文件shiro版本<!--shiro--><dependency><groupId>org.apache.......
  • PUTTY 使用vi命令编辑文件的时候Backspace老出问题解决方案
    问题原因分析系统自带的vi命令存在这个问题,需要安装vim来解决问题安装vim编辑器删除vim-common模块apt-getremovevim-common安装vim模块apt-getinstallvim再使用vi命令,......
  • CF1550F 题解
    题意传送门数轴上顺次有\(n\)个点\(a_1<a_2<\cdots<a_n\)。有一只小青蛙,初始时在\(a_s\)处。小青蛙有两个参数:步长\(d\)和灵活程度\(k\)。其中,步长\(d\)......
  • 题解 CF1703G Good Key, Bad Key
    先放个代码。intn,k;cin>>n>>k;vector<vector<int>>a(n+5,vector<int>(35));for(inti=1;i<=n;i++){cin>>a[i][0];for(intj=1;j......
  • 网络搭建赛题解法
    网络搭建赛题解法准备工作1.所有云主机都要设置ip2.关闭防火墙和selinuxsetenforce0systemctlstopfirewall3.所有主机配置yum源mkdir/mnt/cdrommount/dev/cd......
  • 最小公倍数
    #include<stdio.h>intmain(){intm=0;intn=0;scanf("%d%d",&m,&n);//输入intk=(m>n?m:n);//求m和n的最大值while(k%m!=0||k%n!=0)//求最......
  • 最小公倍数--小技巧
    问题:求两个整数a和b的中最小公倍数(最小公倍数是指整除a和b)分析:方法一常规做法,引入变量m,让m与a和b同时求余。若不为0,则m加1开始循环,直到同时为0停止,输入m。方法二引入变量i......
  • ABC250简要题解
    重点在于简要A,B,C,语法题,跳了。D是埃筛求个质数枚举一下,跳了、E神秘的哈希。对于前\(i\)个数搞个可加哈希,这样能\(O(1)\)比较。给了个神秘的哈希方式是\(\suma......
  • jeecg问题解决方案
    1.jeecg数据库脚本问题  注意:jeecg3.5.2之前版本,不需要数据库脚本,程序会自动初始化数据库。从3.5.2+开始,需要手工执行SQL脚本,初始化数据库。  2.  Eclipse内存溢......