传送门:Gift

题意:由n(n<=1e9)个珍珠构成的项链,珍珠包含幸运数字(有且仅由4或7组成),取区间[L,R]内的数字,相邻的数字不能相同,且旋转得到的相同的数列为一种,为最终能构成多少种项链。

分析:这是我做过的最为综合的一道题目(太渣了),首先数位dp筛选出区间[L,R]内的幸运数字总数,dp[pos]表示非限制条件下还有pos位含有的幸运数字个数,然后记忆化搜索一下,随便乱搞的(直接dfs不知会不会超时,本人做法900+ms险过,应该直接dfs会超时),再不考虑旋转相同的情况,可以dp再构造矩阵,dp[i][0]表示到达第i位时,最后一个珠子与第一个珠子不同,dp[i][1]表示到达第i位最后一个珠子与第一个相同,则状态转移方程为:

dp[i][0]=dp[i-1][0]*(m-2)+dp[i-1][1]*(m-1)(m为幸运数字种类).

dp[i][1]=dp[i-1][0]*1

上面构造矩阵快速幂求出总数后再由Burnside定理+容斥得到答案,这个问题较为常见,可参考poj2888做法。

#include <stdio.h>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstdlib>
#define LL long long
#define N 25
#define mod 1000000007
using namespace std;
/**************************矩阵快速幂**************************/
struct matrix
{
LL m[][];
void init()
{
for(int i=;i<;i++)
for(int j=;j<;j++)
m[i][j]=(i==j);
}
}M;
matrix mult(matrix a,matrix b)
{
matrix c;
memset(c.m,,sizeof(c.m));
for(int k=;k<;k++)
for(int i=;i<;i++)
{
if(a.m[i][k]==)continue;
for(int j=;j<;j++)
{
c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%mod;
}
} return c;
}
matrix quick_pow(matrix a,int n)
{
matrix res;
res.init();
while(n)
{
if(n&)res=mult(res,a);
a=mult(a,a);
n>>=;
}
return res;
}
LL calc(LL n,LL m)
{
matrix res;
res.m[][]=m-;res.m[][]=m-;
res.m[][]=;res.m[][]=;
res=quick_pow(res,n-);
// printf("m=%lld n=%lld res=%lld\n",m,n,res.m[0][1]);
return m*res.m[][]%mod;
}
/**************************矩阵快速幂**************************/
LL POW(LL a,LL n)
{
LL res=;
a%=mod;
while(n)
{
if(n&)res=res*a%mod;
a=a*a%mod;
n>>=;
}
return res;
}
/**********************容斥**************************/
#define MAXN 12
#define MAXM 32000
#define EPS 1e-8
bool p[MAXM];
vector<int> prime;
vector<int> factor;
vector<int> primefactor;
void Init() {
int i, j;
prime.clear();
memset(p, true, sizeof(p));
for (i = ; i < ; i++) {
if (p[i]) {
for (j = i * i; j < MAXM; j += i)
p[j] = false;
}
}
for (i = ; i < MAXM; i++) {
if (p[i])
prime.push_back(i);
}
}
void Prime(int x) {
int i, tmp;
primefactor.clear();
tmp = (int) (sqrt((double) x) + EPS);
for (i = ; prime[i] <= tmp; i++) {
if (x % prime[i] == ) {
primefactor.push_back(prime[i]);
while (x % prime[i] == )
x /= prime[i];
}
}
if (x > )
primefactor.push_back(x);
}
int Mul(int x, int &k) {
int i, ans;
ans = ;
for (i = k = ; x; x >>= , i++) {
if (x & ) {
k++;
ans *= primefactor[i];
}
}
return ans;
}
LL Phi(int x) {
int i, j, t, ans, tmp;
Prime(x);
ans = ;
t = (int) primefactor.size();
for (i = ; i < ( << t); i++) {
tmp = Mul(i, j);
if (j & )
ans += x / tmp;
else
ans -= x / tmp;
}
return (x - ans) %mod;
}
/**********************容斥**************************/
LL solve(LL n,LL m)
{
LL ans=;
for(int i=;i*i<=n;i++)
{
if(n%i==)
{
int a=i,b=n/i;
if(i*i==n)
{
ans=(ans+Phi(n/a)*calc(a,m))%mod;
}
else
{
ans=(ans+Phi(n/a)*calc(a,m))%mod;
ans=(ans+Phi(n/b)*calc(b,m))%mod;
}
}
}
ans=ans*POW(n,mod-)%mod;
return ans;
}
/************************数位dp**********************/
LL dig[],dp[];
LL dfs(int pos,int flag,int limit,int fzore)
{
if(pos==)return flag;
if(!fzore&&!limit&&~dp[pos])return dp[pos];
int len=limit?dig[pos]:;
LL ans=;
for(int i=;i<=len;i++)
{
if(i==||i==||i==){
if(fzore&&i==)ans+=dfs(pos-,,i==len&&limit,);
else if(i==||i==)ans+=dfs(pos-,,i==len&&limit,);}
}
if(!fzore&&!limit)dp[pos]=ans;
return ans;
}
LL fun(LL x)
{
int len=;
if(x<)return ;
while(x)
{
dig[++len]=x%;
x/=;
}
return dfs(len,,,);
}
/************************数位dp**********************/
int main()
{
LL n,L,R;
Init();
memset(dp,-,sizeof(dp));
while(scanf("%lld%lld%lld",&n,&L,&R)>)
{
LL num=fun(R)-fun(L-);
if(n==)
{
puts("");continue;
}
if(n==)
{
printf("%d\n",num%mod);
continue;
}
printf("%d\n",solve(n,num)); }
}

HUST 1569(Burnside定理+容斥+数位dp+矩阵快速幂)的更多相关文章

  1. hdu5564--Clarke and digits(数位dp+矩阵快速幂)

    Clarke and digits 问题描述 克拉克是一名人格分裂患者.某一天,克拉克变成了一个研究人员,在研究数字. 他想知道在所有长度在[l,r]之间的能被7整除且相邻数位之和不为k的正整数有多少 ...

  2. BZOJ3329 Xorequ(数位dp+矩阵快速幂)

    显然当x中没有相邻的1时该式成立,看起来这也是必要的. 于是对于第一问,数位dp即可.第二问写出dp式子后发现就是斐波拉契数列,矩阵快速幂即可. #include<iostream> #i ...

  3. BZOJ 3329 Xorequ:数位dp + 矩阵快速幂

    传送门 题意 现有如下方程:$ x \oplus 3x = 2x $ 其中 $ \oplus $ 表示按位异或. 共 $ T $ 组数据,每组数据给定正整数 $ n $,任务如下: 求出小于等于 $ ...

  4. BZOJ3329: Xorequ(二进制数位dp 矩阵快速幂)

    题意 题目链接 Sol 挺套路的一道题 首先把式子移一下项 \(x \oplus 2x = 3x\) 有一件显然的事情:\(a \oplus b \leqslant c\) 又因为\(a \oplus ...

  5. 2018.09.27 hdu5564Clarke and digits(数位dp+矩阵快速幂)

    传送门 好题啊. 我只会写l,rl,rl,r都很小的情况(然而题上并没有这种数据范围). 但这个dp转移式子可以借鉴. 我们用f[i][j][k]f[i][j][k]f[i][j][k]表示当前在第i ...

  6. bnuoj 34985 Elegant String DP+矩阵快速幂

    题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 We define a kind of strings as elegant s ...

  7. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

  8. 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂

    [题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...

  9. 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂

    [题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...

随机推荐

  1. IOS开发之UILabel动态高度设置方法

    项目中有这样的需求,要显示一本书的概述,默认显示2行,点击展开按钮,显示全部,点击收回,有显示2行. 开始的时候按钮事件中,可能写的是这样一段代码: if (isExpand) { [lblBrief ...

  2. Jquery Mobile转场特效之slide | 小小iPhone开发

    Jquery Mobile转场特效之slide | 小小iPhone开发 2012 Jquery Mobile转场特效之slide 作者:小小   发布:2012-12-12 14:03   分类:j ...

  3. sharepoint具体错误提示

    sharepoint页面发生错误时,默认不会显示具体错误信息,只显示“未知错误”提示.需要修改配置站点的webconfig文件,才能显示出具体错误提示.具体方法如下: 将safeMode中的CallS ...

  4. LINQ to SQL的一些简单用法

    static void Main(string[] args) { var personList = new List<Person> { new Person() { PersonID= ...

  5. os内存使用管理之linux篇

    os内存使用管理之linux篇 看一下LINUX内存机制是怎么运作的,了解了基础知识,对于理解和操作是有很大帮助的. 抛砖引玉: Linux 优先使用物理内存,当物理内存还有空闲时,linux是不会施 ...

  6. 重操JS旧业第五弹:函数

    函数在任何编程语言中起着非常重要的位置,因为他是功能的最小单元,在js中函数是一种类型 Function 1 申明与定义 显示声明:function cc(){};函数名其实是函数的一个指针,函数名某 ...

  7. Mockito文档-单元测试技术

    Overview  Package   Class  Use  Tree  Deprecated  Index  Help     PREV CLASS   NEXT CLASS FRAMES     ...

  8. POJ 2175 spfa费用流消圈

    题意:给出n栋房子位置和每栋房子里面的人数,m个避难所位置和每个避难所可容纳人数.然后给出一个方案,判断该方案是否最优,如果不是求出一个更优的方案. 思路:很容易想到用最小费用流求出最优时间,在与原方 ...

  9. Linux账号管理(二)

    再次声明,整理此系列Linux博客,主要目的不是介绍各种命令,而是去探索命令背后的理论. 本篇主要介绍用户的创建与删除. 创建用户主要用到useradd命令,在用此命令时可以指定各种参数.一般默认就可 ...

  10. Mac AppStore 登陆提示 未知错误

    Mac Book 登陆的时候提示未知错误,刚开始以为是需要内建网卡后来才得知: 如果是黑苹果,或者是网卡没有对应上的,需要内建网卡 mac 系统默认的是无线网卡en0 其他都网卡 以此类推 如果是ma ...