题目链接

(BZOJ) https://www.lydsy.com/JudgeOnline/problem.php?id=5330
(Luogu) https://www.luogu.org/problem/P4607

题解

首先观察一些性质。
一个回文串可以轮换产生多少个本质不同的串?周期那么多个。
可是有一种特殊情况,就是对于长度为偶数的回文串\(a=ss^Rss^Rss^R...ss^R\) (\(s^R\)表示\(s\)的reverse), 如果轮换位数恰好等于周期的一半,那么会产生\(a'=s^Rss^Rss^Rs...s^Rs\), 这是另一个回文串,因此会算重!
于是我们大胆猜测,设\(a\)的周期为\(T\), 则当\(T\)为偶数时对答案的贡献为\(\frac{T}{2}\), 否则为\(T\).
一个简单的证明是,串\(a\)轮换\(d\)位和轮换\(T-d\)位所得到的串互为reverse,若得到了回文串,那么\(d=T-d\).

那么现在我们的问题简化了: 设长度为\(n\)字符集为\(m\)周期为\(T\)的回文串有\(g(T)\)个,要求的就是\(\sum_{d|n}g(d)h(d)\), 其中\(h(d)\)为贡献。
现在考虑怎么算周期为\(T\)的回文串: 设\(G(T)\)表示有多少个回文串满足\(T\)是它的周期(但不是最小周期,即周期是\(T\)的因数),则\(G(T)=m^{\lceil \frac{T}{2}\rceil}\).
且有\(G(T)=\sum_{d|T}g(d)\), 由莫比乌斯反演可得\(g(T)=sum_{d|T}\mu(\frac{T}{d})G(d)\).
然后直接枚举因数裸求就可以得到54至60分(当然也可以\(g(T)=G(T)-\sum_{d|T}g(d)\), 但是这样由于复杂度较劣只有30至36分,期望得分是官方题解里给的)

当\(n\le 10^{18}\)时,\(n\)的约数个数\(d(n)\le 103680\).
推式子: \(\sum_{d|n}\sum_{d'|d}G(d')\mu(\frac{d}{d'})h(d)=\sum_{d|n}\sum_{d'|\frac{n}{d}}G(d)\mu(d')h(dd')\)
观察式子,当\(d\)为奇数\(\frac{n}{d}\)为偶数时,每一个奇数都会和一个偶数配成一对,并且\(\mu\)值相反。因此这种情况对答案贡献为\(0\).
在其他情况下,一定满足\(h(dd')=h(d)d'\), 即\(\sum_{d|n}G(d)h(d)\sum_{d'|\frac{n}{d}}d'\mu(d')\)
考虑\(\sum_{d|n}d\mu(d)\)的组合意义,易得原式等于\(\sum_{d|n}G(d)h(d)\prod_{p|\frac{n}{d}}(1-p)\), 其中\(p\)为质数
DFS所有的质因数即可。

时间复杂度\(O(n^{\frac{1}{4}}\log n+d(n)\log n)\), 其中\(d(n)\)为\(n\)的约数个数.

代码

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<algorithm>
#include<vector>
#define llong long long
#define pll pair<llong,llong>
#define mkpr make_pair
using namespace std;const int N = 103680;
vector<pll> pfac;
llong P;llong quickmul(llong x,llong y,llong mod=P)
{return (x%mod)*(y%mod)%mod;
}
llong quickpow(llong x,llong y,llong mod=P)
{llong cur = x,ret = 1ll;for(int i=0; y; i++){if(y&(1ll<<i)) {ret = quickmul(ret,cur,mod)%mod; y-=(1ll<<i);}cur = quickmul(cur,cur,mod);}return ret;
}namespace Pollard_Rho
{const int N = 15;const int LGM = 64;llong fc[LGM+2];llong a[N+2];llong m;int n;llong ans;llong quickmul(llong x,llong y,llong mod=P){llong tmp=(x*y-(llong)((long double)x/mod*y+1.0e-8)*mod)%mod;return tmp<0 ? tmp+mod : tmp;}llong quickpow(llong x,llong y,llong mod=P){llong cur = x,ret = 1ll;for(int i=0; y; i++){if(y&(1ll<<i)) {ret = quickmul(ret,cur,mod)%mod; y-=(1ll<<i);}cur = quickmul(cur,cur,mod);}return ret;}llong gcd(llong x,llong y) {return y==0 ? x : gcd(y,x%y);}llong absl(llong x) {return x>=0 ? x : -x;}llong ssrand(llong x,llong c,llong y) {return (quickmul(x,x,y)+c)%y;}bool Miller_Rabin(llong x){if(x==1) return false;if(x==2) return true;if((x&1)==0) return false;llong y = x-1,t = 0ll;while((y&1)==0) y>>=1,t++;for(int i=1; i<=5; i++){llong bas = rand()%(x-1)+1;llong cur = quickpow(bas,y,x);for(int j=1; j<=t; j++){llong tmp = quickmul(cur,cur,x);if(tmp==1 && cur!=1 && cur!=x-1) return false;cur = tmp;}if(cur!=1) return false;}return true;}llong pollard_rho(llong x,llong c){llong i = 1,k = 2;llong y = rand()%(x-1)+1; llong t = y;while(true){i++;y = ssrand(y,c,x);llong d = gcd(absl(t-y),x);if(d>1 && d<x) return d;if(t==y) return x;if(i==k){t = y;k<<=1;}}}void factorize(llong x,llong c){if(x==1) return;if(Miller_Rabin(x)){n++; fc[n] = x;return;}llong p = x,k = c;while(p>=x) p = pollard_rho(p,c--);factorize(p,k); factorize(x/p,k);}void Factorize(llong _m){m = _m;n = 0;factorize(m,120);sort(fc+1,fc+n+1);pfac.clear();for(int i=1; i<=n; i++){if(fc[i]==fc[i-1]) {pfac[pfac.size()-1].second++;}else {pfac.push_back(mkpr(fc[i],1));}}}
}llong n,m;
llong ans;void dfs(int pos,llong x,llong coe)
{if(pos==pfac.size()){if((x&1ll) && (!((n/x)&1ll))) {return;}llong tmp = quickmul(coe,quickmul(quickpow(m,(x+1)>>1),(x&1)?x:(x>>1)));ans = (ans+tmp)%P;return;}for(int i=0; i<=pfac[pos].second; i++){dfs(pos+1,x,i==pfac[pos].second?coe:quickmul(coe,(P+1-pfac[pos].first%P)));x = x*pfac[pos].first;}
}int main()
{srand(time(NULL));int T; scanf("%d",&T);while(T--){scanf("%lld%lld%lld",&n,&m,&P);Pollard_Rho::Factorize(n);
//      for(int i=0; i<pfac.size(); i++) printf("(%lld,%lld) ",pfac[i].first,pfac[i].second); puts("");ans = 0ll;dfs(0,1ll,1ll);printf("%lld\n",ans);}return 0;
}

BZOJ 5330 Luogu P4607 [SDOI2018]反回文串 (莫比乌斯反演、Pollard Rho算法)相关推荐

  1. P4619 [SDOI2018]旧试题(莫比乌斯反演,建图优化三重枚举,三元环计数,神仙好题,超级清晰易懂)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 P4619 [SDOI2018]旧试题(莫比乌斯反演,三元环计数) Problem 计算: ∑i=1A ...

  2. bzoj 2565: 最长双回文串 manacher算法

    2565: 最长双回文串 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem. ...

  3. BZOJ 2565: 最长双回文串

    2565: 最长双回文串 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1769  Solved: 895 [Submit][Status][Dis ...

  4. BZOJ 2565 最长双回文串 Manacher

    题目大意: 定义双回文串G是指一个可以被拆分成两个部分(S和T)的字符串G = S + T, 且S和T都是回文串的串, G自己本身可以不是回文串 给出一个长度为n ( 2 <= n <= ...

  5. bzoj 4755: [Jsoi2016]扭动的回文串 manachar+hash+二分

    题意 JYY有两个长度均为N的字符串A和B. 一个"扭动字符串S(i,j,k)由A中的第i个字符到第j个字符组成的子串与B中的第j个字符到第k个字符组成的子串拼接而成. 比如,若A='XYZ ...

  6. [BZOJ]4755: [Jsoi2016]扭动的回文串

    Time Limit: 10 Sec  Memory Limit: 512 MB Description JYY有两个长度均为N的字符串A和B. 一个"扭动字符串S(i,j,k)由A中的第i ...

  7. 【数据结构与算法】之深入解析“分割回文串”的求解思路与算法示例

    一.题目要求 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是回文串,返回 s 所有可能的分割方案. 回文串是正着读和反着读都一样的字符串. 示例 1: 输入:s = "aab ...

  8. 最长回文 HDU - 3068(求最长回文串的长度【马拉车算法Manacher】)

    马拉车算法 Manacher's Algorithm 是用来查找一个字符串的最长回文子串的线性方法,由一个叫 Manacher 的人在 1975 年发明的,这个方法的最大贡献是在于将时间复杂度提升到了 ...

  9. LeetCode 131. 分割回文串【字符串,回溯算法】

    131. 分割回文串 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 .返回 s 所有可能的分割方案. 回文串 是正着读和反着读都一样的字符串. 示例 1: 输入:s = &q ...

最新文章

  1. MS_SQL_获取字符串最后出现的字符串及位置
  2. Apache工具类ToStringBuilder用法简介
  3. 2019年CV领域,值得一看的综述文章!
  4. 一步步学习 Spring Data 系列之JPA(一)
  5. RabbitMQ 的这些骚操作你知道吗?
  6. Calling handler.OnEndpointsUpdate报错原因
  7. JAVA 多用户商城系统b2b2c---配置中心和消息总线
  8. 电脑有电流声怎么解决_【音响杂谈】音响有电流声怎么办 - 音响杂音的处理办法...
  9. kij是不是c语言语句,C语言考试题库及答案分析(总35页).doc
  10. linux docker状态,Linux之Docker
  11. 基于51单片机的数字电压表
  12. ctf 网络安全比赛简介
  13. Python:nii格式的核磁共振图像(MRI)的读取、处理、显示操作(以缩放操作举例)
  14. DM数据库的启停以及数据库状态检查
  15. ORACLE之热备份
  16. SEO系列三:周珍谈新手如何快速入门
  17. 转ARM 指令 详解
  18. 【转载】透视“专利恶霸”系列之二 蜕变后的苹果有了新玩法
  19. Java核心技术 卷1-总结-11
  20. 05-旭日X3派测评——Open Cv Pangolin等库安装ORB_SLAM2 安装运行

热门文章

  1. 云炬WEB开发教程2-2 node.js和npm介绍和安装
  2. 不同系统下的shell的不同_方向盘越来越重:转向系统不同 原因也不同
  3. dev c++怎么调试_「正点原子NANO STM32开发板资料连载」第十八章 USMART 调试组件...
  4. 推荐常用算法之-基于内容的推荐(转自-BreezeDeus博主)
  5. 3DSlicer24:Module-Create Scripted
  6. VTK修炼之道35:边缘检测_Laplace算子
  7. PIC单片机精通_串口通信模块C实现
  8. Sqlserver中查询存储过程是否包含某些文本
  9. 使用cordova serve build以及tomcat进行web 调试。
  10. 数据段描述符和代码段描述符(二)——《x86汇编语言:从实模式到保护模式》读书笔记11