题面传送门

看到题目我们显然可以将题目拆分成两部分:首先求出有多少个符合要求的珠子 \(c\),这样我们就可以将每种珠子看成一种颜色,题目也就等价于有多少种用 \(c\) 种颜色染长度为 \(n\) 的环的方法,满足相邻格子颜色不同,可以通过旋转重合的染色方案算同一种,这就是题目的第二部分。显然两部分是独立的,因此可以分开来计算。

首先考虑怎样求出 \(c\) 的值,注意到这里涉及 \(\gcd\),故可以套路地想到莫比乌斯反演,记 \(f(i)\) 为珠子上三个数 \(\gcd\) 恰好为 \(i\) 的方案数,\(g(i)\) 为珠子上三个数 \(\gcd\) 为 \(i\) 的倍数的方案数,那么显然有 \(g(i)=\sum\limits_{i\mid j}f(j)\),莫反一下显然有 \(f(i)=\sum\limits_{i\mid j}\mu(\dfrac{j}{i})g(j)\),最终答案 \(c=f(1)=\sum\limits_{i=1}^a\mu(i)g(i)\),故只需求出 \(g(i)\) 即可求出 \(f(1)\),接下来考虑怎样求出 \(g(i)\),由于珠子上三个数都是 \(i\) 的倍数,那么该值就等价于珠子上三个数都不超过 \(m=\lfloor\dfrac{a}{i}\rfloor\) 的方案数,而由于此题要求本质不同的珠子个数,故考虑 Burnside 定理,假设珠子上三个数为 \((a,b,c)\),那么 \((a,b,c)\) 与 \((a,c,b),(b,a,c),(b,c,a),(c,a,b),(c,b,a)\) 是本质上相同的,即 \((a,b,c)\times p\),其中 \(p\) 是可以是任意一个三阶置换,我们对于每个 \(p\) 都构造一个以小置换 \((a,b,c)\) 为元素的大置换 \(P_p\),其中 \((a,b,c)\) 在 \(P_p\) 中对应的元素为 \((a,b,c)\times p\),那么显然这 \(3!=6\) 个大置换构成了一个置换群,我们要求的即为这个置换群中等价类的个数,而由 Burnside 定理其就等于 \(\dfrac{1}{6}\sum\limits_{p}c(P_p)\),再由 Polya 定理 \(P_p\) 中不动点的个数就是 \(m^{p\text{中置换环的个数}}\),故 \(g(i)=\dfrac{1}{6}(2m+3m^2+m^3)\),整除分块一下即可在 \(\sqrt{a}\) 的时间内求出 \(c\)(虽然不用整除分块问题也不大)

接下来考虑题目的第二部分,我们将全部 \(c\) 种珠子编号 \(1,2,\cdots,c\),那么题目等价于求有多少种用 \(c\) 种颜色染长度为 \(n\) 的环的方法,满足相邻格子颜色不同,可以通过旋转重合的染色方案算同一种。看到本质不同,继续考虑 Burnside 定理,根据模板题的套路它就等于 \(\dfrac{1}{n}\sum\limits_{d\mid n}\varphi(\dfrac{n}{d})q(d)\),其中 \(q(d)\) 为用 \(c\) 种颜色染长度为 \(d\) 的纸片,满足相邻格子颜色不同,首尾格子颜色也不同的方案数。首先考虑怎样求出 \(\varphi(\dfrac{n}{d})\),暴力 \(\sqrt{n}\) 求复杂度会达到 \(d(n)\sqrt{n}\),无法通过,不过我们发现我们计算的 \(\varphi(i)\) 都是 \(n\) 的因数,故考虑将 \(n\) 分解质因数,然后一遍 DFS 预处理出所有 \(n\) 的因数的 \(\varphi\),用 std::map 存储,这样复杂度可降到 \(\sqrt{n}+d(n)\log n\)。最后考虑怎样求 \(p(d)\),一个很 naive 的想法是 \(p(d)=c(c-2)(c-1)^{d-2}\),不过这显然是错误的,因为对于第一个格子的颜色与第 \(d-1\) 个格子颜色相同与不同的情况,第 \(d\) 个格子染色的方案数也是不同的,因此考虑分两种情况讨论,若第一个格子的颜色与第 \(d-1\) 个格子颜色相同,那么可视作对于长度为 \(d-2\) 的纸片,将最后一个格子劈成两份,并拿一份放到开头,再在中间插入一个格子,即 \(p(d)\leftarrow p(d-2)\times(c-1)\),若第一个格子的颜色与第 \(d-1\) 个格子颜色不同,那么可视作对于长度为 \(d-1\) 的纸片,在最后一个格子后面插入一个格子,即 \(p(d)\leftarrow p(d-1)\times(c-2)\)。故 \(p(d)=p(d-2)\times(c-1)+p(d-1)\times(c-2)\),特征根方程推推,\(x^2-(c-2)x-(c-1)=0\),解得 \(x_1=-1,x_2=c-1\),待定系数法设 \(p(d)=\alpha(-1)^{d}+\beta(c-1)^d\),那么显然 \(p(1)=0,p(2)=c(c-1)\),故 \(\begin{cases}\beta(c-1)-\alpha=0\\\beta(c-1)^2+\alpha=c(c-1)\end{cases}\),解得 \(\begin{cases}\alpha=c-1\\\beta=1\end{cases}\),故 \(p(d)=(c-1)(-1)^d+(c-1)^d\),大功告成。

最后还有一点,就是由于 \(n\le 10^{14}\),可能出现 \((10^9+7)\mid n\) 的情况,这种情况下 \(n\) 不存在 \(\mod 10^9+7\) 意义下的逆元,因此需将模数变为 \((10^9+7)^2\),这样在最后乘以 \(\dfrac{1}{n}\) 之前的答案 \(ans\) 一定是 \(10^9+7\) 的倍数,这样我们只需将 \(ans\) 除以 \(10^9+7\),然后再乘上 \(\dfrac{n}{10^9+7}\) 的逆元即可,这时候需要写龟速乘,否则会爆 ll。

const int MAXV=1e7;
int mu[MAXV+5],pr[MAXV/10+5],prcnt=0,sum[MAXV+5];
bitset<MAXV+5> vis;
void sieve(int n){
mu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){pr[++prcnt]=i;mu[i]=-1;}
for(int j=1;j<=prcnt&&pr[j]*i<=n;j++){
vis[pr[j]*i]=1;
if(i%pr[j]==0) break;
mu[i*pr[j]]=-mu[i];
}
}
for(int i=1;i<=n;i++) sum[i]=sum[i-1]+mu[i];
}
ll smul(ll x,ll y,ll mod){
if(x<0) x=(x%mod+mod)%mod;
if(y<0) y=(y%mod+mod)%mod;
ll ret=0;
for(;y;y>>=1,x=(x+x)%mod) if(y&1) ret=(ret+x)%mod;
return ret;
}
ll qpow(ll x,ll e,ll mod){
ll ret=1;
for(;e;e>>=1,x=smul(x,x,mod)) if(e&1) ret=smul(ret,x,mod);
return ret;
}
const ll MOD1=1e9+7;
const ll MOD2=MOD1*MOD1;
ll INV6_1=qpow(6,MOD1-2,MOD1);
ll INV6_2=qpow(6,MOD1*(MOD1-1)-1,MOD2);
ll MOD,INV6;map<ll,ll> phi;
void dfs(int x,vector<pair<ll,int> > fac,ll mul,ll phim){
if(x==fac.size()) return phi[mul]=phim,void();
for(int i=0;i<=fac[x].se;i++){
if(i){
mul=mul*fac[x].fi;
if(i==1) phim=phim*(fac[x].fi-1);
else phim=phim*fac[x].fi;
} dfs(x+1,fac,mul,phim);
}
}
ll calc(ll k,ll n){return smul(k-1,((n&1)?-1:1)+qpow(k-1,n-1,MOD),MOD);}
void solve(){
ll n,k=0;int a;scanf("%lld%d",&n,&a);
if(n%MOD1==0) MOD=MOD2,INV6=INV6_2;
else MOD=MOD1,INV6=INV6_1;
for(int l=1,r;l<=a;l=r+1){
r=(a/(a/l));ll lim=a/l,cnt=0;
cnt=(cnt+smul(lim,smul(lim,lim,MOD),MOD))%MOD;
cnt=(cnt+smul(3*lim,lim,MOD))%MOD;cnt=(cnt+2*lim)%MOD;
cnt=smul(cnt,sum[r]-sum[l-1],MOD);cnt=smul(cnt,INV6,MOD);
k=(k+cnt)%MOD;//printf("%d %d %lld\n",l,r,cnt);
} //printf("%lld\n",k);
vector<ll> fac;ll tmp=n;
vector<pair<ll,int> > fac_dec;
for(ll i=1;i*i<=n;i++) if(n%i==0){
fac.pb(i);if(n/i!=i) fac.pb(n/i);
}
for(ll i=2;i*i<=n;i++) if(tmp%i==0){
int cnt=0;
while(tmp%i==0) tmp/=i,cnt++;
fac_dec.pb(mp(i,cnt));
} if(tmp>1) fac_dec.pb(mp(tmp,1));
phi.clear();dfs(0,fac_dec,1,1);ll ans=0;
for(ll x:fac) ans=(ans+smul(phi[n/x],calc(k,x),MOD))%MOD;
// printf("%lld\n",ans);
if(n%MOD1) ans=smul(ans,qpow(n,MOD1-2,MOD1),MOD1);
else ans=smul(ans/MOD1,qpow(n/MOD1,MOD1*(MOD1-1)-1,MOD2),MOD2);
printf("%lld\n",ans%MOD1);
}
int main(){
int qu;scanf("%d",&qu);sieve(MAXV);
while(qu--) solve();
return 0;
}

洛谷 P3307 - [SDOI2013]项链(Burnside 引理+数论)的更多相关文章

  1. 洛谷P3307 [SDOI2013]项链 [polya定理,莫比乌斯反演]

    传送门 思路 很明显的一个思路:先搞出有多少种珠子,再求有多少种项链. 珠子 考虑这个式子: \[ S3=\sum_{i=1}^a \sum_{j=1}^a\sum_{k=1}^a [\gcd(i,j ...

  2. 洛谷 P4708 - 画画(Burnside 引理+组合数学)

    洛谷题面传送门 神仙题 %%%%%%%%%%%%%%%%%%%% 题解搬运人来了 首先看到本质不同(无标号)的图计数咱们可以想到 Burnside 引理,具体来说,我们枚举一个排列 \(p\),并统计 ...

  3. 洛谷P1446/BZOJ1004 Cards Burnside引理+01背包

    题意:有n张牌,有R+G+B=n的3种颜色及其数量,要求用这三种颜色去染n张牌.n张牌有m中洗牌方式,问在不同洗牌方式下本质相同的染色方案数. 解法:这道题非常有意思,题解参考Hzwer学长的.我这里 ...

  4. 洛谷 P3307: bzoj 3202: [SDOI2013] 项链

    题目传送门:洛谷P3307.这题在bzoj上是权限题. 题意简述: 这题分为两个部分: ① 有一些珠子,每个珠子可以看成一个无序三元组.三元组要满足三个数都在$1$到$m$之间,并且三个数互质,两个珠 ...

  5. 洛谷P1063 能量项链(区间DP)(环形DP)

    To 洛谷.1063 能量项链 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的 ...

  6. 『题解』洛谷P1063 能量项链

    原文地址 Problem Portal Portal1:Luogu Portal2:LibreOJ Portal3:Vijos Description 在\(Mars\)星球上,每个\(Mars\)人 ...

  7. [洛谷P3304] [SDOI2013]直径

    洛谷题目链接:[SDOI2013]直径 题目描述 小Q最近学习了一些图论知识.根据课本,有如下定义.树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度.如果一棵树有N个节点,可以证明其有且仅 ...

  8. Bzoj3197/洛谷3296 [SDOI2013]刺客信条assassin(树的重心+树Hash+树形DP+KM)

    题面 Bzoj 洛谷 题解 (除了代码均摘自喻队的博客,可是他退役了) 首先固定一棵树,枚举另一棵树,显然另一棵树只有与这棵树同构才有可能产生贡献 如果固定的树以重心为根,那么另一棵树最多就只有重心为 ...

  9. 洛谷 P1063 能量项链

    题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定 ...

随机推荐

  1. kettle使用

    Kettle的安装及简单使用 目录 Kettle的安装及简单使用 一.kettle概述 二.kettle安装部署和使用 Windows下安装 案例1:MySQL to MySQL 案例2:使用作业执行 ...

  2. 第七次Scrum Metting

    日期:2021年5月5日 会议主要内容概述:前后端对接,以及接下来的测试优化等工作. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 徐宇龙 后端 测试数据模块和 ...

  3. dice_game攻防世界进阶区

    dice_game XCTF 4th-QCTF-2018 前言,不得不说,虽然是个简单题但是还是要记录一下,来让自己记住这些东西. 考察的知识点是: 1.cdll_loadlibrary加载对应库使得 ...

  4. 零基础入门该如何实现C 语言面向对象编程(很有帮助)

    零基础如果更快更好的入门C语言,如何在枯燥的学习中找到属于自己的兴趣,如果把学习当成一种事务性的那以后的学习将会很难有更深入的进步,如果带着乐趣来完成学习那将越学越有意思这样才会让你有想要更深入学习的 ...

  5. 面试官问:说说你对Java函数式编程的理解

    常见的面试问题 总结一下,在Java程序员的面试中,经常会被问到类似这样的问题: Java中的函数式接口是什么意思? 注解 @FunctionalInterface 的作用是什么? 实现一个函数式接口 ...

  6. 算法:数字推盘游戏--重排九宫(8-puzzle)

    一.数字推盘游戏 数字推盘游戏(n-puzzle)是一种最早的滑块类游戏,常见的类型有十五数字推盘游戏和八数字推盘游戏等.也有以图画代替数字的推盘游戏.可能Noyes Palmer Chapman在1 ...

  7. (转)Linux中的文件描述符与打开文件之间的关系

    转:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述     在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文 ...

  8. Luogu P1084 疫情控制 | 二分答案 贪心

    题目链接 观察题目,答案明显具有单调性. 因为如果用$x$小时能够控制疫情,那么用$(x+1)$小时也一定能控制疫情. 由此想到二分答案,将问题转换为判断用$x$小时是否能控制疫情. 对于那些在$x$ ...

  9. Loto实践干货(8) 实测 保险丝 用示波器带电流探头

    本文用LOTO示波器和5A的电流探头来实验两种常见类型的保险丝的保护曲线.一种是熔断型的,另一种是自恢复型的.我们通常需要在一些电路中对电流过大的情况做保护,比如防止用户把输出源短路,比如防止用户对电 ...

  10. linux&c 进程控制 课后习题

    (声明:本篇博客只是博主自己的理解,加以整理,目的是总结刚学过的进程知识,不一定绝对正确,非常愿意听客官您提出宝贵意见.) Q1:进程中的全局数据段(全局变量),局部数据段(局部变量),静态数据段的分 ...