Iris‘ Food

Iris‘ Food

题目描述

猫猫 Iris 又在玩 oql 的键盘了。
在 T 天的时间里,每一天 Iris 会在玩 oql 键盘的时候敲下若干个字符,而这些字符恰好全都是 0 ∼ 9 0∼9 09 这10 个阿拉伯数字。经过统计,数字 i 有 a i a_i ai 个。oql 每天可能会给 Iris 喂一定数量的猫粮。他决定,在这 ∑ i = 0 9 a i \sum^9_{i=0}a_i i=09ai个数字里选择 m m m 个,经过重新排列后形成一个十进制下 m m m 位、且不包含前导 0 的非负整数 x x x,然后 oql 将在这天给 Iris 投喂 x x x 克的猫粮。
然而,Iris 还是一只小猫,不宜食用太多的猫粮。因此 oql 想让这个数字尽可能小。请你帮助 Iris 计算出她每天能得到多少猫粮。由于答案可能很大,你只需要输出答案对 1 0 9 + 7 10^9+7 109+7取模的结果。请注意,你需要输出的是最小答案模 1 0 9 + 7 10^9+7 109+7 后的结果,而不是 x x x mod 1 0 9 + 7 10^9+7 109+7的最小值。

Input

第一行一个正整数 T T T ( 1 ≤ T ≤ 1 0 4 ) (1≤T≤10^4) (1T104),表示天数。
2 ∼ ( T + 1 ) 2∼(T+1) 2(T+1) 行,每行 11 11 11 个由空格分隔的非负整数 m , a 0 , a 1 , ⋯ , a 9 ( 1 ≤ m ≤ 1 0 9 , 0 ≤ a i ≤ 1 0 9 ) m,a_0,a_1,⋯,a_9(1≤m≤10^9,0≤a_i≤10^9) m,a0,a1,,a9(1m109,0ai109),表示第 i i i 天的情况。
数据保证有解,即至少能形成一个 m m m 位不包含前导 0 0 0 的非负整数。

Output

对于每一天,输出一行一个整数,表示 Iris 这一天能得到的猫粮对 1 0 9 + 7 10^9+7 109+7 取模后的结果。

Sample Input 1

3
3 1 0 0 0 3 0 0 0 0 0
1 2 0 0 0 0 0 0 0 0 0
4 0 1 1 1 3 0 0 0 0 0

Sample Output 1

404
0
1234

解题思路

  • 快速幂的算法
const ll mod=1e9+7;

ll qmi(ll a,ll b)
{
    //当b = 0,p = 1时
    //①不 % p ,结果是 1
    //② % p ,结果是 0(正确答案)
    ll res=1%mod;//注意:5 0 1
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;//右移 1 位
    }
    return res;
}

代码内容

// #include <iostream>
// #include <algorithm>
// #include <cstring>
// #include <sstream>//整型转字符串
// #include <stack>//栈
// #include <deque>//堆/优先队列
// #include <queue>//队列
// #include <map>//映射
// #include <unordered_map>//哈希表
// #include <vector>//容器,存数组的数,表数组的长度
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll mod=1e9+7;

ll qmi(ll a,ll b)
{
    //当b = 0,p = 1时
    //①不 % p ,结果是 1
    //② % p ,结果是 0(正确答案)
    ll res=1%mod;//注意:5 0 1
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;//右移 1 位
    }
    return res;
}

void solve()
{
    ll m,a[10];
    cin>>m;
    for(ll i=0;i<10;i++)
        cin>>a[i];

    if(m==1&&a[0])
    {
        cout<<0<<endl;
        return;
    }

    ll t;
    for(ll i=1;i<10;i++)
    {
        if(a[i])
        {
            t=i;
            m--;
            a[i]--;
            break;
        }
    }

    ll res=t*qmi(10,m)%mod;
    for(ll i=0;i<10;i++)
    {
        ll x=min(m,a[i]);
        if(x) (res+=i*(qmi(10,x)-1)%mod*qmi(9,mod-2)%mod*qmi(10,m-x)%mod)%=mod;
        m-=x;
    }

    cout<<res<<endl;
}

int main()
{
    ll t;
    cin>>t;

    while(t--)
    {
        solve();
    }
    
    return 0;
}
  • 16
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pretty Boy Fox

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值