//poj2089
/*
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n;
int m;
int dp[20][10];
int a[20];
int dfs(int pos,int pre,int state,bool limit)
{
if(pos==-1)return 1;
if(!limit&&dp[pos][state]!=-1)return dp[pos][state];
int up=limit?a[pos]:9;
int ans=0;
for(int i=0;i<=up;i++){
if(pre==6&&i==2)continue;
if(i==4)continue;
ans+=dfs(pos-1,i,i==6,limit&&i==a[pos]);
}
if(!limit)dp[pos][state]=ans;
return ans;
}
int solve(int n)
{
int i=0;
while(n){
a[i++]=n%10;
n/=10;
}
return dfs(i-1,-1,0,true);
}
int main()
{
while(cin>>m>>n){
memset(dp,-1,sizeof(dp));
cout<<solve(n)-solve(m-1)<<endl;
}
return 0;
}
*/
//hdu4734
/*
int dp[20][10005];
int digit[20];
int getvalue(int a)
{
int i=0;
int ans=0;
while(a){
ans=ans+((a%10)*(1<<i));
i++;
a/=10;
}
return ans;
}
int dfs(int pos,int state,int limit)
{
if(state<0)return 0;
if(pos==0)return state>=0;
int ans=0;
int up=limit?digit[pos]:9;
for(int i=0;i<=up;i++){
ans+=dfs(pos-1,state-i*(1<<(pos-1)),limit&&i==digit[pos]);
}
if(!limit)dp[pos][state]=ans;
return ans;
}
int solve(int b,int a)
{
int pos=0;
while(b){
digit[pos++]=b%10;
b/=10;
}
return dfs(pos,getvalue(a),1);
}
int main()
{
int t;
cin>>t;
while(t--){
memset(dp,-1,sizeof(dp));
cin>>a>>b;
cout<<solve(b,a);
}
return 0;
}
*/
//poj3252
/*
int n,m;
int dp[50][50];//dp[i][j]表示枚举到第i位,前面0的个数和1的个数差,为了防止中间出现dp[i][j]为负数但有可能是合法结果,此处hash一下,dp[i][j]+32
//最后判断结果是否>=32判断该方案是否合法
int digit[50];
int getvalue(int x)
{
int i=0;
while(x){
digit[i++]=x&1;
x=x>>1;
}
return dfs(pos-1,32,true,true);
}
int dfs(int pos,int state,bool lead,bool limit)//这里前导0有影响,要加上lead
{
if(pos==-1)return state>=32;
int up=limit?digit[pos]:1;
int ans=0;
for(int i=0;i<=up;i++){
if(i==0&&lead)ans+=dfs(pos-1,state,lead&&i==0,limit&&i==digit[pos]);//有前导0不计数
else ans+=dfs(pos-1,state+=(i==0)?1:0,lead&&i==0,limit&&i==digit[pos]);
}
if(!limit&&!lead)dp[pos][state]=ans;
return ans;
}
int main()
{
memset(dp,-1,sizeof(dp));
while(cin>>m>>n){
cout<<getvalue(n)-getvalue(m-1)<<endl;
}
return 0;
}
*/
/*
//hdu3709
ll m,n;
ll dp[20][2005][20];
int digit[20];
ll dfs(int pos,int state,int pivot,bool limit)
{
if(pos<=0)return state==0;
if(state<0)return 0;
if(!limit&&dp[pos][state][pivot]!=-1)return dp[pos][state][pivot];
ll ans=0;
int up=limit?digit[pos]:9;
for(int i=0;i<=up;i++){
if(pos>pivot)ans+=dfs(pos-1,state+i*(pos-pivot),pivot,limit&&i==digit[pos]);
else ans+=dfs(pos-1,state-i*(pivot-pos),pivot,limit&&i==digit[pos]);
}
if(!limit)dp[pos][state][pivot]=ans;
return ans;
}
ll solve(ll n)
{
int pos=0;
while(n){
digit[++pos]=n%10;
n/=10;
}
ll ans=0;
//枚举pivot的位置
for(int i=1;i<=pos;i++){
ans+=dfs(pos,0,i,true);
}
//注意前导0不符合条件
return ans - (pos-1); //减去 00 , 000 , 0000的情况
}
int main()
{
int t;
cin>>t;
while(t--){
memset(dp,-1,sizeof(dp));
cin>>n>>m;
ll ans=solve(m)-solve(n-1);
cout<<ans<<endl;
}
return 0;
}
*/
/*
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n;
ll dp[20][20][2][10];
int digit[20];
ll dfs(int pos,int mod,bool limit,int flag,int e)
{
if(pos==-1)return flag&&mod==0;
if(!limit&&dp[pos][mod][flag][e]!=-1)return dp[pos][mod][flag][e];
int up=limit?digit[pos]:9;
ll ans=0;
for(int i=0;i<=up;i++){
ans+=dfs(pos-1,(mod*10+i)%13,limit&&i==up,flag||e==1&&i==3,i);
}
if(!limit)dp[pos][mod][flag][e]=ans;
return ans;
}
ll solve(ll n)
{
int pos=0;
while(n){
digit[pos++]=n%10;
n/=10;
}
return dfs(pos-1,0,true,0,0);
}
int main()
{
memset(dp,-1,sizeof(dp));
while(cin>>n){
cout<<solve(n)<<endl;
}
return 0;
}
*/
/*
* 如果一个整数符合下面3个条件之一,那么我们就说这个整数和7有关——
1、整数中某一位是7;
2、整数的每一位加起来的和是7的整数倍;
3、这个整数是7的整数倍;
求一个区间中与7无关的数的平方和
*/
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const long long MOD=1000000007LL;
struct Node
{
long long cnt;//与7无关的数的个数
long long sum;//与7无关的数的和
long long sqsum;//平方和
}dp[20][10][10];//分别是处理的数位、数字和%7,数%7
int bit[20];
long long p[20];//p[i]=10^i
Node dfs(int pos,int pre1,int pre2,bool flag)
{
if(pos==-1)
{
Node tmp;
tmp.cnt=(pre1!=0 && pre2!=0);
tmp.sum=tmp.sqsum=0;
return tmp;
}
if(!flag && dp[pos][pre1][pre2].cnt!=-1)
return dp[pos][pre1][pre2];
int end=flag?bit[pos]:9;
Node ans;
Node tmp;
ans.cnt=ans.sqsum=ans.sum=0;
for(int i=0;i<=end;i++)
{
if(i==7)continue;
tmp=dfs(pos-1,(pre1+i)%7,(pre2*10+i)%7,flag&&i==end);
ans.cnt+=tmp.cnt;
ans.cnt%=MOD;
ans.sum+=(tmp.sum+ ((p[pos]*i)%MOD)*tmp.cnt%MOD )%MOD;
ans.sum%=MOD;
ans.sqsum+=(tmp.sqsum + ( (2*p[pos]*i)%MOD )*tmp.sum)%MOD;
ans.sqsum%=MOD;
ans.sqsum+=( (tmp.cnt*p[pos])%MOD*p[pos]%MOD*i*i%MOD );
ans.sqsum%=MOD;
}
if(!flag)dp[pos][pre1][pre2]=ans;
return ans;
}
long long calc(long long n)
{
int pos=0;
while(n)
{
bit[pos++]=n%10;
n/=10;
}
return dfs(pos-1,0,0,1).sqsum;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
long long l,r;
p[0]=1;
for(int i=1;i<20;i++)
p[i]=(p[i-1]*10)%MOD;
for(int i=0;i<20;i++)
for(int j=0;j<10;j++)
for(int k=0;k<10;k++)
dp[i][j][k].cnt=-1;
scanf("%d",&T);
while(T--)
{
scanf("%I64d%I64d",&l,&r);
long long ans=calc(r);
ans-=calc(l-1);
ans=(ans%MOD+MOD)%MOD;
printf("%I64d\n",ans);
int sum=0;
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
sum+=dp[0][i][j].cnt;
cout<<sum<<endl;
}
return 0;
}
数位dp 模板 poj 2089
最新推荐文章于 2019-07-30 12:52:00 发布