原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1317.html

题目传送门 - 51Nod1317

题意

  称一对字符串(A,B)是相似的,当且仅当满足以下条件:

  (1)字符串A和B都恰好包含N个字符;

  (2)A和B串中的每个字符都是小写字母的前k个字符,即A、B中只可能出现'a','b','c',...,('a'+k-1)这k个字符;

  (3)存在一个字符串C,满足:A+C=C+B。这里的“+”号表示字符串间的链接,即str1+str2 = str1str2,如:“aaa”+“csd”=“aaacsd”。

  现在给出N与k,问有多少种不同的相似字符串对,输出这个结果 mod 1,000,000,007的值。

  说明:两个字符串对(A,B)与(C,D)是不同的,只要 A!=C 或 B!=D。

  $n\leq 10^9$

题解

  显然满足 $A+C=C+B$ 的 $A$ 和 $B$ 循环同构。

  于是原问题变成了有多少对串循环同构。

  我们设 $dp_i$ 表示长度为 $i$ 的 不存在长度小于 $i$ 的循环节的 字符串个数。

  这里的循环节是指满足把该循环节串重复多次可以组成原串的子串。

  显然 $dp_i=k^i -\sum_\limits{j|i} dp_j$ 。

  答案为 $\sum_\limits{i|n} i\times dp_i$ ,因为任意一个循环节长度为 $i$ 的串都可以选择 $i$ 个串与它循环同构。

  由于 $n$ 的因数特别少,因数最多的情况下, $n=735134400$ ,因数个数为 1344 。(我搜了1分钟才搜出来……)

  所以我们可以把 $n$ 的因数搞出来,设因数个数为  $m$ ,然后 $O(m^2)$ DP 解决本问题。

代码

#include <bits/stdc++.h>
using namespace std;
int read(){
int x=0;
char ch=getchar();
while (!isdigit(ch))
ch=getchar();
while (isdigit(ch))
x=(x<<1)+(x<<3)+ch-48,ch=getchar();
return x;
}
const int N=3005,mod=1e9+7;
int n,k,v[N],m,dp[N];
int Pow(int x,int y){
int ans=1;
for (;y;y>>=1,x=1LL*x*x%mod)
if (y&1)
ans=1LL*ans*x%mod;
return ans;
}
int main(){
n=read(),k=read(),m=0;
for (int i=1;i*i<=n;i++)
if (n%i==0){
v[++m]=i;
if (i*i!=n)
v[++m]=n/i;
}
sort(v+1,v+m+1);
int ans=0;
for (int i=1;i<=m;i++){
dp[i]=Pow(k,v[i]);
for (int j=1;j<i;j++)
if (v[i]%v[j]==0)
dp[i]=(dp[i]-dp[j]+mod)%mod;
ans=(1LL*dp[i]*v[i]+ans)%mod;
}
ans=(ans+mod)%mod;
printf("%d\n",ans);
return 0;
}

  

51Nod1317 相似字符串对 容斥原理 动态规划的更多相关文章

  1. 【BZOJ1090】[SCOI2003]字符串折叠(动态规划)

    [BZOJ1090][SCOI2003]字符串折叠(动态规划) 题面 BZOJ 洛谷 题解 区间\(dp\).设\(f[i][j]\)表示压缩\([i,j]\)区间的最小长度.显然可以枚举端点转移.再 ...

  2. Bzoj 1042: [HAOI2008]硬币购物 容斥原理,动态规划,背包dp

    1042: [HAOI2008]硬币购物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1747  Solved: 1015[Submit][Stat ...

  3. java----构造回文字符串java(动态规划)【手写演算残图】

    问题描述 草稿解决过程 (字丑别喷) 代码实现 import java.util.Scanner; /** * Created by Admin on 2017/3/26. */ public cla ...

  4. BZOJ1090 [SCOI2003]字符串折叠 区间动态规划 字符串

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1090 题意概括 折叠的定义如下: 1. 一个字符串可以看成它自身的折叠.记作S 2. X(S)是X ...

  5. UOJ#185. 【ZJOI2016】小星星 容斥原理 动态规划

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ185.html 题解 首先暴力DP是 $O(3^nn^3)$ 的,大家都会. 我们换个方向考虑. 假设我们 ...

  6. BZOJ1042 HAOI2008硬币购物(任意模数NTT+多项式求逆+生成函数/容斥原理+动态规划)

    第一眼生成函数.四个等比数列形式的多项式相乘,可以化成四个分式.其中分母部分是固定的,可以多项式求逆预处理出来.而分子部分由于项数很少,询问时2^4算一下贡献就好了.这个思路比较直观.只是常数巨大,以 ...

  7. Regular Expression Matching,regex,正则表达式匹配,利用动态规划

    问题描述:Implement regular expression matching with support for '.' and '*'. '.' Matches any single char ...

  8. 每日一题 - 剑指 Offer 48. 最长不含重复字符的子字符串

    题目信息 时间: 2019-07-02 题目链接:Leetcode tag: 动态规划 哈希表 难易程度:中等 题目描述: 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度 ...

  9. leetcode动态规划题目总结

    Hello everyone, I am a Chinese noob programmer. I have practiced questions on leetcode.com for 2 yea ...

随机推荐

  1. why should the parameter in copy construction be a reference

    if not, it will lead to an endless loop!!! # include<iostream> using namespace std; class A { ...

  2. 【原创】测试基础之http_load(1)简介、安装、使用

    http_load-09Mar2016官方:https://acme.com/software/http_load/ 一 简介 http_load - multiprocessing http tes ...

  3. Less常用知识点

    上篇文章介绍了如何安装Less,我们将所有东西都写在.less里面,最后通过命令将.less转换成.css文件,就可以放入到项目里用了.今天了解一些less常用知识点. 1.变量:声明两个变量,一个是 ...

  4. Math中的floor,round和ceil方法总结

    floor向下取整,返回不大于的最大整数  Math.floor(1.4)=1.0ceil向上取整,返回不小于的最小整数  Math.ceil(1.4)=2.0round 四舍五入,将原来的数字加入0 ...

  5. 声明寄存器ROM

    :] ROM [:] ; integer i; initial begin ;i<=;i=i+) begin ROM[i] <= {{'b0}}; end end 同时可以考虑双端口ROM ...

  6. Netty多人聊天室

    在简单聊天室的代码中修改ChatServerHandler类,就可以模拟多人聊天的功能 package com.cppdy.server; import io.netty.channel.Channe ...

  7. Django框架之Form组件

    一.初探Form组件 在介绍Form组件之前,让大家先看看它强大的功能吧!Go... 下面我们来看看代码吧! 1.创建Form类 from django.forms import Form from ...

  8. laravel 路由缓存

    使用路由缓存之前,需要知晓路由缓存只能用于控制器路由,不能用于闭包路由,如果路由定义中包含闭包路由将无法进行路由缓存,只有将所有路由定义转化为控制器路由或资源路由后才能执行路由缓存命令: php ar ...

  9. MySQL数据查询子查询语句

  10. WIN 7 使用shutdown命令设置电脑自动关机

    使用组合键“WIN + R”,在弹出的对话窗“运行”中输入“cmd”,点击“确定”按钮或直接按回车键“Enter”.  设置电脑在一定时间后关机,比如60分钟,在弹出的对话框中,输入“shutdown ...