5.30 杂题选讲

这次请了老师来讲……没有毒瘤的CDW了)(好吧其实一样毒瘤


T1,T2:

什么水题,不打了。


T3:

数位DP。$O(10n\log r)$ 的应该不难想。然后我就想着把乘积变成 $n$ 除多少的形式,发现只有 $\sqrt{n}$ 种取值。

然而有更简单的做法……发现乘积的质因子只有 $2,3,5,7$,记录一下次数即可。

实际状态数只有约 $6000$。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; 
#define FOR(i,a,b) for(int i=(a);i<=(b);i++)
#define ROF(i,a,b) for(int i=(a);i>=(b);i--)
#define MEM(x,v) memset(x,v,sizeof(x))
ll l,r,dp[20][33][22][17][12];
int n,bit[20],bl;
inline int da(int x){
    if(x==4) return 2;
    if(x==8) return 3;
    if(x%2==0) return 1;
    return 0;
}
inline int db(int x){
    if(x==9) return 2;
    if(x%3==0) return 1;
    return 0;
}
inline int dc(int x){return x==5;}
inline int dd(int x){return x==7;}
ll dfs(int pos,int a,int b,int c,int d,ll pro,bool lim,bool zero){
    if(pro>n) return 0;
    if(!pos) return !zero;
    if(!lim && !zero && ~dp[pos][a][b][c][d]) return dp[pos][a][b][c][d];
    int upr=lim?bit[pos]:9;
    ll ans=0;
    if(zero) ans=dfs(pos-1,0,0,0,0,1,lim&&!upr,1);
    FOR(i,1,upr) ans+=dfs(pos-1,a+da(i),b+db(i),c+dc(i),d+dd(i),pro*i,lim&&i==upr,0); 
    if(!lim && !zero) dp[pos][a][b][c][d]=ans;
    return ans;
}
ll solve(ll r){
    bl=0;
    while(r) bit[++bl]=r%10,r/=10;
    MEM(dp,-1);
    return dfs(bl,0,0,0,0,1,1,1);
}
int main(){
    scanf("%d%lld%lld",&n,&l,&r);
    printf("%lld\n",solve(r-1)-solve(l-1));
}
View Code

 

posted @ 2019-05-30 22:15  ATS_nantf  阅读(139)  评论(0编辑  收藏  举报