http://acm.hdu.edu.cn/showproblem.php?pid=4507
无聊写个水DP
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
#define rep(i,l,r) for(int i=(l),_=(r);i<=_;i++)
#define per(i,r,l) for(int i=(r),_=(l);i>=_;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define INE(i,u) for(int i=head[u];~i;i=e[i].next)
#define LL long long
#define X first
#define Y second
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
////////////////////////////////////////////////
const LL mod=1000000007;
LL l,r;
struct data{LL cnt,s1,s2;};
data dp[20][7][7];
int bit[20];
LL pow10[20];
////////////////////////////////////////////////
data dfs(int pos,int bitsum,int sum,bool limit)
{
if(!pos) return bitsum!=0&&sum!=0?(data){1,0,0}:(data){0,0,0};
if(!limit && ~dp[pos][bitsum][sum].cnt) return dp[pos][bitsum][sum];
int upp=limit?bit[pos]:9;
data ans=(data){0,0,0};
rep(i,0,upp) if(i!=7)
{
data ret=dfs(pos-1,(bitsum+i)%7,(sum*10+i)%7,limit&&i==upp);
ans.cnt=ans.cnt+ret.cnt;
if(ans.cnt>=mod) ans.cnt-=mod;
LL x=i*pow10[pos]%mod;
ans.s1=ans.s1+ret.s1+ret.cnt*x%mod;
if(ans.s1>=mod) ans.s1-=mod;
if(ans.s1>=mod) ans.s1-=mod;
ans.s2+=ret.s2;
if(ans.s2>=mod) ans.s2-=mod;
ans.s2+=2*ret.s1%mod*x%mod;
if(ans.s2>=mod) ans.s2-=mod;
ans.s2+=ret.cnt*x%mod*x%mod;
if(ans.s2>=mod) ans.s2-=mod;
}
if(!limit) dp[pos][bitsum][sum]=ans;
return ans;
}
LL cal(LL n)
{
for(*bit=0;n;n/=10) bit[++*bit]=n%10;
return dfs(*bit,0,0,1).s2;
}
////////////////////////////////////////////////
void input()
{
cin>>l>>r;
}
void solve()
{
LL ans=cal(r)-cal(l-1);
if(ans<0) ans+=mod;
cout<<ans<<endl;
}
////////////////////////////////////////////////
int main()
{
freopen("_.in","r",stdin); freopen("_.out","w",stdout);
MS(dp,-1);
pow10[1]=1; rep(i,2,20) pow10[i]=pow10[i-1]*10%mod;
rep(i,1,read())
input(),solve();
return 0;
}

321

被折叠的 条评论
为什么被折叠?



