hdu 4507 吉哥系列故事――恨7不成妻 数位dp

来源:互联网 发布:包拼车软件怎么样 编辑:程序博客网 时间:2024/05/17 12:01

dp[i][mod1][mod2][0] 为 第i位后 数位和%7为mod1 数值%7为mod2 的满足条件的累加值的和
dp[i][mod1][mod2][1] 为 第i位后 数位和%7为mod1 数值%7为mod2 的满足条件的累加平方值的和
dp[i][mod1][mod2][2] 为 第i位后 数位和%7为mod1 数值%7为mod2 的满足条件的数量和
然后累加值 和 数量都是最普通的数位dp基本模型可以求出
平方和 的状态转移可以由 (a+b) ^ 2这个式子转移 既(a * ten[i]) ^ 2 * sum2 + sum1 + 2 * a * ten[i] * sum0 * sum2
注意取模

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#define mod 1000000007ll#define LL long longusing namespace std;LL dp[31][11][11][3]; // 0 累加和 1 平方和 2 数量和int sym[31][7][7];LL x[100], l, ten[111];void dfs(LL i, LL pre1, LL pre2, bool e, LL &sum1, LL &sum2, LL &sum3){     if(i == -1)     {        if(pre1 % 7 != 0 && pre2 % 7 != 0) sum3 = 1;        return ;     }     if(e && sym[i][pre1 % 7][pre2 % 7])     {          sum1 += dp[i][pre1 % 7][pre2 % 7][0];          sum2 += dp[i][pre1 % 7][pre2 % 7][1];          sum3 += dp[i][pre1 % 7][pre2 % 7][2];          sum1 %= mod;          sum2 %= mod;          sum3 %= mod;          return ;     }     int Max = e ? 9 : x[i];     for(int j = 0; j <= Max; j++)     {         if(j != 7)         {          LL sum11 = 0;          LL sum22 = 0;          LL sum33 = 0;          dfs(i - 1, pre1 + j, pre2 + ten[i] * j, !(!e && j == x[i]), sum11, sum22, sum33);          sum3 += sum33;          sum1 += sum11 + (sum33 % mod)* (j % mod) * (ten[i] % mod);          sum2 += (j * (ten[i] % mod) * j % mod * (ten[i] % mod) % mod * (sum33 % mod) % mod + sum22 % mod + 2 * (ten[i] % mod) * j % mod * (sum11 % mod) % mod) % mod;          sum1 %= mod;          sum2 %= mod;          sum3 %= mod;         }    }     if(e)     {         sym[i][pre1 % 7][pre2 % 7] = 1;         dp[i][pre1 % 7][pre2 % 7][0] = sum1;         dp[i][pre1 % 7][pre2 % 7][1] = sum2;         dp[i][pre1 % 7][pre2 % 7][2] = sum3;         dp[i][pre1 % 7][pre2 % 7][0] %= mod;         dp[i][pre1 % 7][pre2 % 7][1] %= mod;         dp[i][pre1 % 7][pre2 % 7][2] %= mod;     }}LL cal(LL n){   l = 0;   while(n)   {     x[l++] = n % 10;     n /= 10;   }   LL ans1 = 0, ans2 = 0, ans3 = 0;   dfs(l - 1, 0, 0, 0, ans1, ans2, ans3);   return ans2;}int main(){    ten[0] = 1;    for(int i = 1; i<= 20; i++) ten[i] = ten[i - 1] * 10;    int t;    scanf("%d", &t);    while(t--)    {        LL a, b;        scanf("%I64d %I64d", &a, &b);        printf("%I64d\n", (cal(b) - cal(a - 1) + mod) % mod);    }    return 0;}
0 0
原创粉丝点击