hdu 4933 孙子定理+数位dp

//code 1
//dp[2][2]
//mod 2520(9*8*7*5)
//anss=anss%(anss%9);
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define f1 first
#define f2 second
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define initial 1,n,1
#define N 105
#define T 15
#define clr(x,y) memset(x,y,sizeof(x))
const int inf=0x3f3f3f3f;
const long long INF=1LL<<50;
using namespace std;
typedef long long LL;
typedef pair <int, int> PII;
template<typename X> inline bool minimize(X&p,X q){if(p<=q)return 0;p=q;return 1;}
template<typename X> inline bool maximize(X&p,X q){if(p>=q)return 0;p=q;return 1;}
struct node{
    int n,s;
    node(int x=0,int y=0):n(x),s(y){}
};
char str1[N],str2[N];
node dp[N][2][2],dp2[N][2][2][T];
bool vis[N][2][2],vis2[N][2][2][T];
int num[N],len,id,l2;
const int mod=2520;
int mod2[T]={7000003,7000009,7000033,7000057,7000061,
             7000069,7000087,7000109,7000121,7000127,
             7000129,7000157,7000163,7000171,7000181};


node dfs(int w,int se,int flag)
{   if (w==0) return node(1,0);
    if (!se&&vis[w][l2][flag]) return dp[w][l2][flag] ;
    int max=se?num[w]:9;
    node tmp,re;
    int rr;
    for (int i=0;i<=max;i++)
        {   if (flag&&i) rr=((len-w)%2==0)?1:-1; else rr=1;
            tmp=dfs(w-1,se&&(i==max),flag&&(i==0));
            re.s+=i*tmp.n*rr;
            re.s-=tmp.s*rr;
            re.n+=tmp.n;
        }
    re.s%=mod;
    re.n%=mod;
    if (!se)
            {   vis[w][l2][flag]=1;
                dp[w][l2][flag]=re;
            }
    return re;

}
node dfs2(int w,int se,int flag)
{   if (w==0) return node(1,0);
    if (!se&&vis2[w][l2][flag][id]) return dp2[w][l2][flag][id];
    int max=se?num[w]:9;
    node tmp,re;
    int rr;
    for (int i=0;i<=max;i++)
        {   if (flag&&i) rr=((len-w)%2==0)?1:-1; else rr=1;
            tmp=dfs2(w-1,se&&(i==max),flag&&(i==0));
            re.s+=i*tmp.n*rr;
            re.s-=tmp.s*rr;
            re.n+=tmp.n;
        }
    re.s%=mod2[id];
    re.n%=mod2[id];
    if (!se)
            {   vis2[w][l2][flag][id]=1;
                dp2[w][l2][flag][id]=re;
            }
    return re;

}
int calc(char*s,int ff,int gg)
{
    len=strlen(s);
    if (len==1&&s[0]=='0'&&ff==1) return 0;
    for (int i=1;i<=len;i++)
        num[i]=s[len-i]-'0';
    if (ff){
            num[1]--;
            int i=1;
            while (num[i]<0)    {num[i]+=10; num[i+1]--; i++;}
            if (!num[len]&&len>1) len--;
           }
    l2=len%2;
    if (!gg)return dfs(len,1,1).s;
    return dfs2(len,1,1).s;

}
void doit()
{   int ans2,ans1,anss;
    scanf("%s",str1);
    scanf("%s",str2);
    int ff=0;
    for (int i=0;i<T;i++)
        {
            id=i;
            ans2=calc(str2,0,1);
            ans1=calc(str1,1,1);
            anss=(ans2-ans1+mod2[i])%mod2[i];
            if (anss) {ff=1; break;}
        }
    if (!ff) {printf("Error!\n"); return;}
    ans2=calc(str2,0,0);
    ans1=calc(str1,1,0);
    anss=(ans2-ans1+mod)%mod;
    if (anss%9==0) {printf("0\n"); return;}
    anss=anss%(anss%9);
    printf("%d\n",anss);

}
int main()
{
    memset(vis,0,sizeof(vis));
    memset(vis2,0,sizeof(vis2));
    int cas;
    scanf("%d",&cas);
    while (cas--) doit();

}


//code 2
//dp[3]
//anss=mod 9;
//finalans=mod anss;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#define pb push_back
#define mp make_pair
#define eps 1e-9
#define zero(x) (fabs(x)<eps)
#define pi acos(-1.0)
#define f1 first
#define f2 second
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define initial 1,n,1
#define N 105
#define T 15
#define clr(x,y) memset(x,y,sizeof(x))
const int inf=0x3f3f3f3f;
const long long INF=1LL<<50;
using namespace std;
typedef long long LL;
typedef pair <int, int> PII;
template<typename X> inline bool minimize(X&p,X q){if(p<=q)return 0;p=q;return 1;}
template<typename X> inline bool maximize(X&p,X q){if(p>=q)return 0;p=q;return 1;}

struct node{
    int n,s;
    node(int x=0,int y=0):n(x),s(y){}
};
char str1[N],str2[N];
node dp[N][3][10],dp2[N][3][T];
//0 all 0
//1 +
//2 -
bool vis[N][3][10],vis2[N][3][T];
int num[N],len,id,fid;
int mod;
int mod2[T]={7000003,7000009,7000033,7000057,7000061,
             7000069,7000087,7000109,7000121,7000127,
             7000129,7000157,7000163,7000171,7000181};

node dfs(int w,int flag,int se)
{   if (w==0) return node(1,0);
    if (!se&&vis[w][flag][mod]) return dp[w][flag][mod];
    int max=se?num[w]:9;
    node tmp,re;
    for (int i=0;i<=max;i++)
        {   if (flag)
                {
                    tmp=dfs(w-1,3-flag,se&&(i==max));
                    if (flag==2) re.s-=tmp.n*i; else re.s+=tmp.n*i;
                }
            else{   if (i==0) tmp=dfs(w-1,0,se&&(i==max));else tmp=dfs(w-1,2,se&&(i==max));
                    re.s+=tmp.n*i;
                }
            re.n+=tmp.n;
            re.s+=tmp.s;
        }
    re.n%=mod;
    re.s%=mod;
    if (!se)
            {   vis[w][flag][mod]=1;
                dp[w][flag][mod]=re;
            }
    return re;
}
node dfs2(int w,int flag,int se)
{   if (w==0) return node(1,0);
    if (!se&&vis2[w][flag][id]) return dp2[w][flag][id];
    int max=se?num[w]:9;
    node tmp,re;
    for (int i=0;i<=max;i++)
        {   if (flag)
                {
                    tmp=dfs2(w-1,3-flag,se&&(i==max));
                    if (flag==2) re.s-=tmp.n*i; else re.s+=tmp.n*i;
                }
            else{   if (i==0) tmp=dfs2(w-1,0,se&&(i==max));else tmp=dfs2(w-1,2,se&&(i==max));
                    re.s+=tmp.n*i;
                }
            re.n+=tmp.n;
            re.s+=tmp.s;
        }
    re.n%=mod2[id];
    re.s%=mod2[id];
    if (!se)
            {   vis2[w][flag][id]=1;
                dp2[w][flag][id]=re;
            }
    return re;
}
int calc(char*s,int ff,int gg)
{
    len=strlen(s);
    if (len==1&&s[0]=='0'&&ff==1) return 0;
    for (int i=1;i<=len;i++)
        num[i]=s[len-i]-'0';
    if (ff){
            num[1]--;
            int i=1;
            while (num[i]<0)    {num[i]+=10; num[i+1]--; i++;}
            if (!num[len]&&len>1) len--;
           }
    if (!gg)return dfs(len,0,1).s;
    return dfs2(len,0,1).s;

}
void doit()
{   int ans2,ans1,anss;
    scanf("%s",str1);
    scanf("%s",str2);
    int ff=0;
    for (int i=0;i<T;i++)
        {
            id=i;
            ans2=calc(str2,0,1);
            ans1=calc(str1,1,1);
            anss=(ans2-ans1+mod2[i])%mod2[i];
            if (anss) {ff=1; break;}
        }
    if (!ff) {printf("Error!\n"); return;}

    mod=9;
    ans2=calc(str2,0,0);
    ans1=calc(str1,1,0);
    anss=(ans2-ans1+mod)%mod;
    if (anss==0) {printf("0\n"); return;}
    mod=anss;
    ans2=calc(str2,0,0);
    ans1=calc(str1,1,0);
    anss=(ans2-ans1+mod)%mod;
    printf("%d\n",anss);

}
int main()
{
    memset(vis,0,sizeof(vis));
    memset(vis2,0,sizeof(vis2));
    int cas;
    scanf("%d",&cas);
    while (cas--) doit();
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值