被榜骗了 *** h题不是有手就会吗 怎么就那么点人过啊
不过我还是补a 数位dp 很久很久以前写过 不要62 不过忘得干干净净了
这题应该是数位dp里面最简单的那种吧
链接:https://ac.nowcoder.com/acm/contest/5944/A
来源:牛客网
题目描述
One day, Ks raised a question in this contest.
How many times the digit 7\texttt{7}7 appears in the integer range of [0, n]?
The answer may be very large, please output the answer modulo 1 000 000 0071\,000\,000\,0071000000007.输入描述:
First line contains an integer T (1≤T≤100)T ~ (1 \leq T \leq 100)T (1≤T≤100), indicating the count of questions.
Each of the following T lines contains one integer n (1≤n≤10100000)n ~ (1 \leq n \leq {10}^{100000})n (1≤n≤10100000).输出描述:
Output T lines, one number per line representing the answer.
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
char a[N];
typedef long long ll;
ll dp[N],_10pow[N],c[N];
const ll mod = 1e9+7;
ll ans;
void getans(int len){
for(int i = len; i >= 1; i--)
c[i]=a[len-i+1]-'0';
for(int i = len; i >= 1; i--){
ans+=dp[i-1]*c[i]%mod;//在第i位的情况下 7出现在后面的位
ans%=mod;
if(7<c[i]) ans+=_10pow[i-1];//7出现在第i位
ans%=mod;
}
ll now = 0;
for(int i = 1; i <= len; i++){//当某一位是7的时候 它出现的次数就是 它的后缀部分的大小+1
if(c[i]==7) ans=(ans+now+1)%mod;
now=(now+c[i]*_10pow[i-1])%mod;
}
printf("%lld\n",ans);
}
int main(){
int t;
scanf("%d",&t);
_10pow[0]=1;
for(int i = 1; i < N; i++){
dp[i]=((dp[i-1]*10ll%mod)+_10pow[i-1])%mod;
_10pow[i]=_10pow[i-1]*10ll%mod;
}
while(t--){
scanf("%s",a+1);
ans=0;
int len=strlen(a+1);
getans(len);
}
return 0;
}