首页 > 其他分享 >HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)

时间:2023-01-01 19:32:18浏览次数:56  
标签:HDU equationI int res LL Congruence fac define mod


HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_CCPC

 

 

大致题意:给你一个长度为k的序列a。对于序列c,当 

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_杜教筛_02

 时,

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_CCPC_03

;当

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_杜教筛_04

时,

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_CCPC_05

取[0,m)中任意一个数字。令 

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_莫比乌斯反演 _06

 表示满足 

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_07

 的序列c的方案数。现在让你求 

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_08

                                                          

                                                          


 

首先,根据裴蜀定理,满足

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_CCPC_09

的条件是

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_杜教筛_10

,那么我们不妨分为两种情况处理。对于

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_莫比乌斯反演 _11

的数字,假设他们的gcd为g,那么剩下的数字与g的gcd就要是1。设

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_CCPC_12

的项有k个,加上这个m,设这k+1个数字的gcd为d,那么gcd(d,g)要等于1。由于这k+1个数字里面有一个定值m,所以这个d一定是m的因子。我们令f(d)表示这k+1个数字的gcd为d的方案数。那么开始第一次莫比乌斯反演,有:                                                        

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_13


HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_14

,那么最后的答案就是:                                                          

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_杜教筛_15


HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_杜教筛_16

,于是我们开始第二次莫比乌斯反演:                                                 

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_17

这样,对于g,我们只需要用到gcd为1的,所以我们不妨把第二个参数去掉。整理一下,最后的答案就是:

                                                         

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_18

对于这个g(x),根据莫比乌斯函数的性质,有效的i肯定不会是任意一个质因子的2次幂及以上,所以i一定是x的质因子的线性组合,因此我们可以把这个预处理出来。然后

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_莫比乌斯反演 _19

最多只有

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_伯努利数_20

个,可以分块求和。假设

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_杜教筛_21

的质因子数为cnt,那么计算g部分的开销就是

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_22

,本题cnt最大为9,完全可以接受。那么问题的关键就是如何求h(d)的前缀和了。我们发现,如果令

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_CCPC_23

,那么h(d)就是H(d)和

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_伯努利数_24

的迪利克雷卷积,而H(d)和

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_杜教筛_25

是显然具有积性的。所以说我们可以用积性函数的性质,构造线性筛来求解h(d)的前缀和。但是注意到,本题的数据范围是

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_杜教筛_26

,而且还有多组数据,即使是线性的筛法也无法满足条件。所以我们这里考虑用杜教筛。

杜教筛了解一下:​​javascript:void(0)​​

简单来说就是,利用迪利克雷卷积的恒等变换,使得一个原本不容易求的积性数论函数的前缀和,变成两个容易求的积性数论函数运算,最后转化成

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_27

的形式,其中A(n)表示辅助的容易求和的积性数论函数的前缀和。之后对于前

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_28

的S(n),用构造线性筛直接打表计算;对于后面的大的部分,利用上面的式子分块记忆化搜索计算。可以证明这样子做的复杂度是O(

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_28

)的。对于本题,令

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_杜教筛_30

,我们可以这么推导:                               

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_伯努利数_31

最后这个东西满足杜教筛的形式,关于前面这个幂和,我们同样有方法计算:​​https://www.zybuluo.com/yang12138/note/848419​

本题的话选用伯努利数的方法来计算幂和,即

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_32

。经过曲折之后,我们就可以在O(

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_28

)的时间复杂度内求出这个h(d)的前缀和S(d)。最后的答案

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_18

,分成两部分分块求和即可。最后总的时间复杂度是

HDU 6439 2018CCPC网络赛 Congruence equationI(杜教筛 + 莫比乌斯反演 + 伯努利数)_HDU_35

。具体见代码:

#include<bits/stdc++.h>
#define LL long long
#define mod 1000000007
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define INF 0x3f3f3f3f
#define sf(x) scanf("%d",&x)
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#define sc(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr(x,n) memset(x,0,sizeof(x[0])*(n+5))
#define file(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)

using namespace __gnu_pbds;
using namespace std;

const int N = 1e6 + 10;
const int K = 1e2 + 10;

int n,m,k,tot,S[N],C[K][K],p[N];
gp_hash_table<int,int> mp;
std::vector<int> pri_fac;
typedef pair<int,int> P;
LL B[K],invk,pw[N];
std::vector<P> fac;
bool isp[N];

LL qpow(LL x,int n)
{
LL res=1;
while(n)
{
if(n&1) res=res*x%mod;
x=x*x%mod; n>>=1;
}
return res;
}

void init()
{
C[0][0]=1;
for(int i=1;i<K;i++) C[i][0]=1;
for(int i=1;i<K;i++)
for(int j=1;j<K;j++)
C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
B[0]=1;
for(int i=1;i<K;i++)
{
for(int j=0;j<i;j++)
B[i]+=C[i+1][j]*B[j]%mod;
B[i]%=mod; B[i]=(mod-B[i])*qpow(i+1,mod-2)%mod;
}
}

void sieve(int n)
{
int sz=0; S[1]=1;
for(int i=2;i<n;i++)
{
if (!isp[i])
{
p[++sz]=i;
pw[i]=qpow(i,k);
S[i]=pw[i]-1;
}
for(int j=1;j<=sz&&p[j]*i<n;j++)
{
int x=i*p[j]; isp[x]=1;
if (i%p[j]==0)
{
S[x]=S[i]*pw[p[j]]%mod;
break;
} else S[x]=S[i]*(pw[p[j]]-1)%mod;
}
}
for(int i=2;i<n;i++) S[i]=(S[i-1]+S[i])%mod;
}

int powsum(int x)
{
if (k==0) return x;
LL res=0,pw=1;
for(int i=1;i<=k+1;i++)
{
pw=pw*(x+1)%mod;
res+=C[k+1][i]*B[k+1-i]%mod*pw%mod;
}
res%=mod;
return res*invk%mod;
}

int s(int x)
{
if (x<tot) return S[x];
if (mp[x]) return mp[x];
LL res=powsum(x);
for(int l=2,r;l<=x;l=r+1)
{
r=x/(x/l);
res-=(r-l+1)*(LL)s(x/l)%mod;
}
res=res%mod+mod;
return mp[x]=res%mod;
}

LL cal(int x)
{
LL res=0;
for(auto i:fac)
{
if (i.first>x) break;
res+=(x/i.first)*(i.second&1?-1:1);
}
return res%mod;
}

int main()
{
int T; sf(T);
init(); int AC=1;
while(T--)
{
sf(n); sf(m);
int g=0; k=0; mp.clear();
for(int i=1;i<=n;i++)
{
int x; sf(x);
if(x==-1)k++;else g=__gcd(g,x);
}
sieve(tot=ceil(pow(m,2.0/3)));
invk=qpow(k+1,mod-2);
if (g==0)
{
printf("Case #%d: %d\n",AC++,s(m));
continue;
}
LL ans=0;
fac.clear();
pri_fac.clear();
for(int i=2;i*i<=g;i++)
{
if (g%i) continue;
pri_fac.pb(i);while(g%i==0) g/=i;
}
if (g>1) pri_fac.pb(g);
int up=1<<pri_fac.size();
for(int i=0;i<up;i++)
{
int cnt=0,d=1;
for(int j=0;j<pri_fac.size();j++)
if (i&(1<<j)) cnt++,d*=pri_fac[j];
fac.pb(P(d,cnt));
}
sort(fac.begin(),fac.end());
int pre=0,cur;
for(int l=1,r;l<=m;l=r+1)
{
r=m/(m/l); cur=s(r);
ans+=(cur-pre)*cal(m/l)%mod;
pre=cur;
}
ans%=mod;
printf("Case #%d: %lld\n",AC++,(ans+mod)%mod);
}
return 0;
}

 

                                            

        

标签:HDU,equationI,int,res,LL,Congruence,fac,define,mod
From: https://blog.51cto.com/u_15765053/5983318

相关文章

  • HDU 6801 Game on a Circle 题解 (推式子,多项式)
    题目链接首先注意到我们对这个环的扫描是一轮一轮进行的,每轮都会从左到右对每个没被删除的元素以p的概率删除。如果我们能对每个\(t(t\in[0,\infin],t是整数)和i\)求出c......
  • hdu:color the ball(差分数组)
    ProblemDescriptionN个气球排成一排,从左到右依次编号为1,2,3….N.每次给定2个整数ab(a<=b),lele便为骑上他的“小飞鸽”牌电动车从气球a开始到气球b依次给每个气球涂......
  • hdu:敌兵布阵(树状数组)
    ProblemDescriptionC国的死对头A国这段时间正在进行军事演习,所以C国间谍头子Derek和他手下Tidy又开始忙乎了。A国在海岸线沿直线布置了N个工兵营地,Derek和Tidy的任务就......
  • HDU 1712 ACboy needs your help
    HDU1712ACboyneedsyourhelp题意:一共有\(n\)轮,给出在每一轮中,选择\(y\)份获得的价值。现在一共可以选择\(m\)份,求最终获得的最大价值是多少。思路:其实相当......
  • hdu: What Are You Talking About(map应用)
    ProblemDescriptionIgnatiusissoluckythathemetaMartianyesterday.Buthedidn’tknowthelanguagetheMartiansuse.TheMartiangiveshimahistoryb......
  • hdu:火车进站问题(stl应用)
    ProblemDescription假设杭州东火车站只有一条铁路,并且所有火车都从一侧进来,从另一侧出去。那么,如果火车A先进站,然后火车B在火车A离开之前就进站,那么火车A直到火车B离开......
  • HDU 1495 非常可乐
    HDU1495非常可乐​ 有一壶S毫升的酒,酒壶容量也是S毫升(没有刻度),现在有两个N毫升和M毫升的酒杯(也都没有刻度),\(S=N+M\),\(0\leS,N,M\le101\),这三只容器均可以......
  • hdu: 阿牛的EOF牛肉串(二维递推)
    ProblemDescription今年的ACM暑期集训队一共有18人,分为6支队伍。其中有一个叫做EOF的队伍,由04级的阿牛、XC以及05级的COY组成。在共同的集训生活中,大家建立了深厚的友谊......
  • hdu:折线分割平面(递推)
    ProblemDescription我们看到过很多直线分割平面的题目,今天的这个题目稍微有些变化,我们要求的是n条折线分割平面的最大数目。比如,一条折线可以将平面分成两部分,两条折线......
  • HDU-2639 Bone Collector ||
    HDU-2639BoneCollector||01背包问题,但是需要输出的是可以获得的第\(k\)大价值。思路:状态定义?我们要求的是第\(k\)大价值,所以当我们得到一个当前第\(k+1\)......