【GDKOI2016】QT与泰剧Code&Details

Details

如果会打数位DP,就没有细节了。
如果运用了前缀和思想就不用打上下界的了。我调了很久才发现我上下不对称,晕+_+
我们知道3的个数是(s-t)/3,如果喜欢可以打个高精度。
不过,其实可以用逆元做。
发现是整除,所以不能直接用逆元。
st3=(st)(st)mod33
那么可以计算出pan=(s-t)mod 3,然后用逆元算出答案,如果pan>0,那么答案还要+1

Code

#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
const int maxn=100007;
const int mo=10007;
using namespace std;
int i,j,k,l,n,m,ans,lens,lent,ans1,kk,ll,tt,a,b,z,ni,pan;
char s[maxn],t[maxn];
int f[maxn][3][2][2],g[maxn][3][2][2],zhi[5]={0,2,3,5,7};
int main(){
    scanf("%s%s",s+1,t+1);
    lens=strlen(s+1);lent=strlen(t+1);
    fo(i,1,lens){
        kk=(kk+s[i]-'0')%3;
        a=(a*10+s[i]-'0')%mo;
    }
    fo(i,1,lent){
        ll=(ll+t[i]-'0')%3;
        b=(b*10+t[i]-'0')%mo;
    }
     ni=3336;
    z=(a-b+mo)%mo;
    pan=(kk-ll+3)%3; 
    f[0][0][1][1]=1;
    fo(i,0,lens-1){
        fo(j,0,2){
            fo(k,0,1){
                fo(tt,0,1){
                    fo(l,1,4){
                        int yi=(zhi[l]+j)%3,er=s[i+1]-'0'; 
                        if(f[i][j][k][tt]){

                            if(k==0){ 
                                f[i+1][yi][0][0]=(f[i][j][k][tt]+f[i+1][yi][0][0])%mo;
                            }
                            else{
                                if(erbreak;
                                if(er>zhi[l]){
                                    f[i+1][yi][0][0]=(f[i][j][k][tt]+f[i+1][yi][0][0])%mo;
                                }
                                else{ 
                                    f[i+1][yi][1][0]=(f[i][j][k][tt]+f[i+1][yi][1][0])%mo;
                                }

                            } 
                        }
                        if(tt){
                            f[i+1][0][0][1]=1;
                        }
                    }
                }
            }
        }
    }
    ans=(ans+f[lens][kk][0][0]+f[lens][kk][1][0]+f[lens][kk][0][1])%mo;
    g[0][0][1][1]=1;
    fo(i,0,lent-1){
        fo(j,0,2){
            fo(k,0,1){
                fo(tt,0,1){
                    fo(l,1,4){
                        int yi=(zhi[l]+j)%3,er=t[i+1]-'0'; 
                        if(g[i][j][k][tt]){
                            if(k==0){ 
                                g[i+1][yi][0][0]=(g[i][j][k][tt]+g[i+1][yi][0][0])%mo;
                            }
                            else{
                                if(erbreak;
                                if(er>zhi[l]){
                                    g[i+1][yi][0][0]=(g[i][j][k][tt]+g[i+1][yi][0][0])%mo;
                                }
                                else{ 
                                    g[i+1][yi][1][0]=(g[i][j][k][tt]+g[i+1][yi][1][0])%mo;
                                }

                            } 

                        }
                        if(tt){
                            g[i+1][0][0][1]=1;
                        }

                    }
                }
            }
        }
    }
    ans1=(ans1+g[lent][kk][0][0]+g[lent][kk][1][0]+g[lent][kk][0][1])%mo;
    ans=(ans-ans1+mo)%mo;
    z=((z-pan+mo)%mo*ni%mo+(pan>0)-ans+mo)%mo;
    printf("%d\n",z);
}

你可能感兴趣的:(数位DP,GDKOI)