zoukankan      html  css  js  c++  java
  • hdu5657 CA Loves Math 分块

    分块,K小的时候dp,K大的时候直接枚举K的倍数然后判断。

    已经尽力优化了,还是没过,,,先留代码,有时间再改。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1e9+10;
    
    const int MOD=3010;
    int A,n,K;
    ll dp[12][(1<<11)+10][MOD+10];
    int cnt[maxn];
    
    int Cnt(int x)
    {
        int res=0;
        while(x){
            if(x%A) res++;
            x/=A;
        }
        return res;
    }
    
    ll DP()
    {
        if(n==0) return K==1?1:0;
        int len=min(A,n);
        REP(i,0,len) REP(j,0,(1<<A)-1) REP(k,0,K-1) dp[i][j][k]=0;
        dp[0][0][0]=1;
        REP(i,0,len-1){
            REP(j,0,(1<<A)-1){
                if(cnt[j]<i) continue;
                REP(k,0,K-1){
                    REP(l,0,A-1){
                        if((j&(1<<l))==0){
                            dp[i+1][j|(1<<l)][(k*A+l)%K]+=dp[i][j][k];
                        }
                    }
                }
            }
        }
        ll res=0;
        REP(j,0,(1<<A)-1) res+=dp[len][j][0];
        return res;
    }
    
    bool vis[12];
    bool check(ll x)
    {
        int t=0;
        MS0(vis);
        while(x){
            t=x%A;
            if(vis[t]) return 0;
            vis[t]=1;
            x/=A;
        }
        return 1;
    }
    
    ll qpow(ll n,ll k)
    {
        ll res=1;
        while(k){
            if(k&1) res*=n;
            n*=n;
            k>>=1;
        }
        return res;
    }
    
    ll Force()
    {
        ll res=0;
        ll limit=qpow(A,min(n,A));
        for(ll i=K;i<=limit;i+=K){
            if(!check(i)) continue;
            res++;
        }
        return res;
    }
    
    void Init()
    {
        REP(i,0,(1<<A)) cnt[i]=Cnt(i);
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        int T;cin>>T;
        while(T--){
            scanf("%d%d%d",&A,&n,&K);
            Init();
            ll ans=0;
            if(K<MOD) ans=DP();
            else ans=Force();
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    /**
    3
    10 2 7
    11 2 3
    2 10 1
    */
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    python中__dict__和dir()
    python学习之copy模块
    python学习之optparse
    python join和split和strip用法
    浅谈 Python 的 with 语句
    Python:itertools模块
    OpenStack Swift client开发
    OpenStack Swift集群部署流程与简单使用
    python bisect模块
    Python中的导入
  • 原文地址:https://www.cnblogs.com/--560/p/5364188.html
Copyright © 2011-2022 走看看