Power of Function

这个题重点是读题。看懂函数,函数最终表示的是 n 写成K进制,K进制的值的和加上长度 -2 就是m。

给你一个 ,k,l,r,求K进制下,[l,r]区间内m的最大值。然后输出当m最大时[l,r]区间最大值和最小值。

 

题解:把l,r转换成K进制, r>l,如果r,l,高位相同,那么求得到最大值M高位肯定也是和这个值一样。然后从第一个位不同开始,想让M值最大,只有两种可能,一种是取r这个值二进制下位减一,然后后面位的全部取 k-1,或者这个位取最大值再继续讨论下一个位。写个DFS就可以,和数位DP有点像。

举个例子 :k=10  ,l=1001,r=1179.

10进制下  l   =   1   0  0  1

                 r  =    1   1  7  9

最前面  1 和 1 是相同的所以要 m最大 肯定  最高位也是 1     b=1 0 0 0

然后从第3位开始dfs(3) 要么这个位取 1, 要么 取 0 后慢慢全取 9,

如果这个位 取 1  就会影响下一个位,所以再DFS(2) 然后发现 要么取7 ,(要么 取 6 后面全为9)

以此类推,最后发现 后面3为  179   099 取得  后面比较大,那么m取最大就是  1099;

还有一些细节要注意,比如   179 ,99是一样打的,因为99只有两位数。还有 0 是没有 比他小1这个数,如果要小1就要向高位借,所以这情况要排除。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
#define bug printf("*********\n");
#define debug(x) cout<<"["<<x<<"]" <<endl;
int t;
LL k,l,r;
vector<LL> v1,v2,mi,mx;
LL p[2000];
LL dfs(LL pos,bool limit) {
    if(pos==-1)return 0;
    if(limit) {
        LL m1,m2;
        m1=dfs(pos-1,1);
        m2=dfs(pos-1,0);
        m1+=v2[pos];
        m2+=v2[pos]-1;
        if(v2[pos]==0)m2=-1;    //排除 为 r pos位 为0情况 
        if(pos==v2.size()-1&&v2[pos]==1)m2--;  // 最高位为 0 m2要减一
        if(m1>m2) {           
            mx[pos]=mi[pos]=v2[pos];
            return m1;
        } else if(m1==m2) {
            mx[pos]=v2[pos];
            mi[pos]=v2[pos]-1;
            for(int i=0; i<pos; i++) {
                mi[i]=k-1;
            }
            return m2;
        } else {
            mx[pos]=mi[pos]=v2[pos]-1;
            for(int i=0; i<pos; i++) {
                mi[i]=mx[i]=k-1;
            }
            return m2;
        }

    } else {
        return (k-1)*(pos+1);
    }
}
int cas=1;
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%lld%lld%lld",&k,&l,&r);
        v1.clear();
        v2.clear();
        LL x=r;
        while(x>0) {
            v2.push_back(x%k);
            x/=k;
        }
        x=l;
        while(x>0) {
            v1.push_back(x%k);
            x/=k;
        }
        while(v1.size()<v2.size()) {
            v1.push_back(0);
        }
        p[0]=1;
        for(int i=1; i<v2.size(); i++) {
            p[i]=p[i-1]*k;
        }
        int pos=v2.size()-1;
        mi.resize(v2.size());
        mx.resize(v2.size());
        while(pos>=0) {
            if(v1[pos]==v2[pos]) {
                mi[pos]=mx[pos]=v2[pos];
            } else break;
            pos--;
        }
        if(pos!=-1)dfs(pos,1);
        LL a=0,b=0,m=0,flag=1;
        for(int i=mx.size()-1; i>=0; i--) {
            m+=mx[i];
            if(mx[i]!=0)flag=0;
            if(flag)m--;
            b+=mx[i]*p[i];
            a+=mi[i]*p[i];
        }
        m=m+mx.size()-2;
        printf("Case #%d: %lld %lld %lld\n",cas++,m,a,b);
    }
    return 0;    //看不懂留言0.0,或者加Q3035536707
}