hdu 5564 Clarke and digits

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=5564

-----------------------------------------------------------------------------------------

刚读完题目感觉像是数位DP,然而仔细看了数据范围后感觉很不可做。

与数位DP题目对比可以发现 此题数据范围要大一些,却没有对每一位进行限制

于是便可以愉快地进行矩阵乘法优化DP啦

如果矩阵构造(将递推式转换为矩阵形式)还不熟练的话 可以参考

挑战程序设计竞赛(第2版) 3.4.2节

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int mod = 1e9 + 7, L = 70 + 1;
int t, l, r, m;
long long raw[L][L], tmp[L][L], a[L][L], b[L][L], f[L];
long long ans1, ans2;
void mul(long long A[L][L], long long B[L][L])
{
    memset(tmp, 0, sizeof tmp);
    for(int i = 0; i < L; ++i)
        for(int j = 0; j < L; ++j)
        {
            for(int k = 0; k < L; ++k)
                tmp[i][j] += A[i][k] * B[k][j] % mod;
            tmp[i][j] %= mod;
        }
    for(int i = 0; i < L; ++i)
        for(int j = 0; j < L; ++j)
            A[i][j] = tmp[i][j];
}
long long solve(int lim)
{
    if(!lim)
        return 0;
    if(lim == 1)
        return 1;
    lim -= 2;
    for(int i = 0; i < L; ++i)
        for(int j = 0; j < L; ++j)
            a[i][j] = b[i][j] = raw[i][j];
    while(lim)
    {
        if(lim & 1)
            mul(a, b);
        mul(b, b);
        lim >>= 1;
    }
    long long tans = 0;
    for(int i = 0; i < L; ++i)
        tans += a[70][i] * f[i] % mod;
    return tans % mod;
}
int main()
{
    for(int i = 1; i <= 9; ++i)
        f[i * 7 + i % 7] = 1;
    f[70] = 1;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d%d%d", &l, &r, &m);
        memset(raw, 0, sizeof raw);
        for(int i = 0; i <= 9; ++i)
            for(int j = 0; j <= 9; ++j)
                if(i + j != m)
                {
                    for(int k = 0; k < 7; ++k)
                    {
                        raw[i * 7 + (k * 10 + i) % 7][j * 7 + k] = 1;
                        if((k * 10 + i) % 7 == 0)
                            ++raw[70][j * 7 + k];
                    }
                }
        raw[70][70] = 1;
        ans1 = solve(l - 1);
        ans2 = solve(r);
        printf("%lld\n", (ans2 - ans1 + mod) % mod);
    }
    return 0;
}
时间: 2024-10-12 17:54:22

hdu 5564 Clarke and digits的相关文章

hdu 5564 Clarke and digits 矩阵快速幂优化数位dp

Clarke and digits Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description Clarke is a patient with multiple personality disorder. One day, Clarke turned into a researcher, did a research on digits. He w

HDU 5564 Clarke and digits 状压dp+矩阵加速

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5564 题意: 求长度在[L,R]范围,并且能整除7的整数的总数. 题解: 考虑最原始的想法: dp[i][j][k]表示长度为i,并且对7取模得到j的以k结尾的数. 则有状态转移方程dp[i+1][(h*10)+l)%7][k]+=dp[i][h][k'](k+k'!=K). 但是i范围是1~10^9,需要矩阵加速. 这里对dp[i][j][k]的[j][k]两个状态进行压缩,得到转移矩阵mat[

【HDOJ】5564 Clarke and digits

DP+快速矩阵幂.注意base矩阵的初始化,不难. 1 /* 5564 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <

HDU 5465 Clarke and puzzle Nim游戏+二维树状数组

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5465 Clarke and puzzle Accepts: 42 Submissions: 269 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 克拉克是一名人格分裂患者.某一天,有两个克拉克(aa和bb)在玩一个方格游戏. 这个方格是一个n*mn∗m的矩阵,每个格子里有一

HDU 5464 Clarke and problem 动态规划

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5464 Clarke and problem Accepts: 130 Submissions: 781 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 克拉克是一名人格分裂患者.某一天,克拉克分裂成了一个学生,在做题. 突然一道难题难到了克拉克,这道题是这样的: 给你nn个数

hdu 5565 Clarke and baton 二分

Clarke and baton Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5565 Description Clarke is a patient with multiple personality disorder. One day, Clarke split into n guys, named 1 to n. They will play a game ca

hdu 5463 Clarke and minecraft

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5463 Clarke and minecraft Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 366    Accepted Submission(s): 193 Problem Description Clarke is a patien

hdu 5465 Clarke and puzzle 二维线段树

Clarke and puzzle Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5465 Description 克拉克是一名人格分裂患者.某一天,有两个克拉克(aa和bb)在玩一个方格游戏. 这个方格是一个n*mn∗m的矩阵,每个格子里有一个数c_{i, j}c?i,j??. aa想开挂,想知道如何打败bb. 他们要玩qq次游戏,每一次做一次操作: 1. 取出当中的一

hdu 5625 Clarke and chemistry

Problem Description Clarke is a patient with multiple personality disorder. One day, Clarke turned into a junior student and took a chemistry exam.  But he did not get full score in this exam. He checked his test paper and found a naive mistake, he w