CCPC-Wannafly Winter Camp Day2 (Div1, onsite)(Power of Function-数位)

CCPC-Wannafly Winter Camp Day2 (Div1, onsite)(Power of Function-数位)_第1张图片
f(n,k)=k进制下n的数位和+位数-2
分别考虑几种情况并check

#include 
using namespace std;
#define For(i,n) for(int i=1;i<=n;i++)
#define Fork(i,k,n) for(int i=k;i<=n;i++)
#define ForkD(i,k,n) for(int i=n;i>=k;i--)
#define Rep(i,n) for(int i=0;i
#define ForD(i,n) for(int i=n;i>0;i--)
#define RepD(i,n) for(int i=n;i>=0;i--)
#define Forp(x) for(int p=pre[x];p;p=next[p])
#define Forpiter(x) for(int &p=iter[x];p;p=next[p])  
#define Lson (o<<1)
#define Rson ((o<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define MEMI(a) memset(a,0x3f,sizeof(a));
#define MEMi(a) memset(a,128,sizeof(a));
#define MEMx(a,b) memset(a,b,sizeof(a));
#define INF (0x3f3f3f3f)
#define F (1000000007)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define vi vector 
#define pi pair
#define SI(a) ((a).size())
#define Pr(kcase,ans) printf("Case #%d: %lld\n",kcase,ans);
#define PRi(a,n) For(i,n-1) cout<
#define PRi2D(a,n,m) For(i,n) { \
						For(j,m-1) cout<
#pragma comment(linker, "/STACK:102400000,102400000")
#define ALL(x) (x).begin(),(x).end()
#define gmax(a,b) a=max(a,b);
#define gmin(a,b) a=min(a,b);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
ll mul(ll a,ll b){return (a*b)%F;}
ll add(ll a,ll b){return (a+b)%F;}
ll sub(ll a,ll b){return ((a-b)%F+F)%F;}
void upd(ll &a,ll b){a=(a%F+b%F)%F;}
inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
	while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();}
	return x*f;
} 
#define MAXN (64)
ll k,l,r;
ll a[MAXN],b[MAXN],len1,len2,len;
void get(ll t,ll &p, ll * a) {
	p=0;
	while(t) {
		a[++p]=t%k;
		t/=k;
	} 
}

ll cc=0;
ll ma=-1;
ll pk[MAXN]={};
ll calc(int len) {
	ll m=0,ans=0;
	bool fl=0,fl2=0;
	cc=0;
	ForD(i,len) {
		if(a[i]==b[i] &&!fl) {
			m+=a[i]; fl2=1;
			cc*=k; cc+=b[i];
			continue;
		}else fl=1;

		if( b[i]) {
			ll p=b[i]-1+(i-1)*(k-1);
			ll swh=(fl2)? (len ) : ( (b[i]-1>0) + i-1 );
			gmax(ans,p+swh+m);
//			cout<
			ll c2=cc*pk[i] + pk[i-1] * (b[i]-1)+ pk[i-1]-1;
			if(ans==p+swh+m) {
				ma=c2;
			}		
		}

		cc*=k; cc+=b[i];
		m+=b[i];
		fl2=1;
	}
	if(!fl) gmax(ans,m+len);
	ll c=len2;
	For(i,len2) c+=b[i];
	gmax(ans,c)
	if(ans==c) ma=r;
	
	ans-=2;
	return ans;
}
ll mi=1e18+1;
ll c[MAXN];
ll c2[MAXN];
bool clr=0;
void upd() {
//	PRi(c,len)
	if(!clr) {
		For(i,len) c2[i]=c[i];
		clr=1;
	}
	ForD(i,len) if(c[i]!=c2[i]) {
		if(c[i]<c2[i]) {
			For(i,len) c2[i]=c[i];
		}
		break;
	}
}
bool ck(ll sum) {
	ll m=0,p=l;
	while(p) {
		m+=p%k+1;
		p/=k;		
	}
	if(m==sum) {
		For(i,len) c[i]=a[i];
		upd();
	}

	m=0,p=r;
	while(p) {
		m+=p%k+1;
		p/=k;		
	}
	if(m==sum) {
		For(i,len) c[i]=b[i];
		upd();
	}
	
}
ll get_mi(int len, ll sum) {
	
	ck(sum);
	
	ll m=0,ans=0;
	int kk=len+1;
	bool fl=0,fl2=0,fl3=0;
	//fl=fendian fl2=0  fl3=pre_unequal
	ForD(i,len) {
		if(a[i]==b[i] &&!fl) {
			fl2=1;
			kk=i;
			c[i]=a[i];
			continue;
		}else fl=1;
		
		if(fl3) {
			//max xxx..[0,b_i-1][***]
			if(b[i]>0) {
				ll m=0;
				bool all0=1;
				Fork(k,i+1,len) c[k]=b[k],m+=c[k];
				Fork(k,i+1,len) all0&=(c[k]==0);
				
				if(!all0) {
					ForkD(k,i+1,len) if(c[k]) {
						m+=k; break;
					}

					if(m<=sum && sum<=m+b[i]-1+(i-1)*(::k-1) ){
						ll g=max(0LL,sum-m-(i-1)*(::k-1));
						c[i]=g;	m+=g;
						ForD(k,i-1) {
							c[k] = max(0LL,sum-m-(k-1)*(::k-1));
							m+=c[k];
						}
						upd();
					}
				}
				else if(b[i]-1>=1){// b[i]!=0
					m+=i;
					if(m+1<=sum && sum<=m+b[i]-1+(i-1)*(::k-1) ){
						ll g=max(1LL,sum-m-(i-1)*(::k-1));
						c[i]=g;	m+=g;
						ForD(k,i-1) {
							c[k] = max(0LL,sum-m-(k-1)*(::k-1));
							m+=c[k];
						}
						upd();
					}
				}
				else {
					if(m<=sum && sum<=m+(i-1)*(::k) ){
						c[i]=0;
						bool flag=0;
						ForD(pos,i-1) {
							// c[pos]!=0 1st 
							if(m+pos+1<=sum && sum<=m+pos+pos*(::k-1) ) {
								m+=pos;
								
								ll g=max(1LL,sum-m-(pos-1)*(::k-1));
								c[pos]=g;	m+=g;
								ForD(k,pos-1) {
									c[k] = max(0LL,sum-m-(k-1)*(::k-1));
									m+=c[k];
								}

								upd();
								m-=pos;
							}
							c[pos]=0;
						}
					}
				}
			}
			
			//min xxx..[a_i+1][***]
			
			if(a[i]+1<k) {
				ll m=0;
				bool all0=1;
				Fork(k,i+1,len) c[k]=a[k],m+=c[k];
				Fork(k,i+1,len) all0&=(c[k]==0);

				if(!all0) {
					ForkD(k,i+1,len) if(c[k]) {
						m+=k; break;
					}
					if(m+a[i]+1<=sum && sum<=m+(i)*(::k-1) ){
						ll g=max(a[i]+1,sum-m-(i-1)*(::k-1));
						c[i]=g;	m+=g;
						ForD(k,i-1) {
							c[k] = max(0LL,sum-m-(k-1)*(::k-1));
							m+=c[k];
						}
						upd();
					}
				}
				else if(a[i]+1>=1){// a[i]!=0
					m+=i;
					if(m+a[i]+1<=sum && sum<=m+(i)*(::k-1) ){
						ll g=max(a[i]+1,sum-m-(i-1)*(::k-1));
						c[i]=g;	m+=g;
						ForD(k,i-1) {
							c[k] = max(0LL,sum-m-(k-1)*(::k-1));
							m+=c[k];
						}
						upd();
					}
				}
			}
			
			
			
		}else {
			if(a[i]+1<b[i]) {

				// a[i]
				ll m=0;
				bool all0=1;
				Fork(k,i+1,len) c[k]=b[k],m+=c[k];
				Fork(k,i+1,len) all0&=(c[k]==0);
	
				if(!all0) {
					ForkD(k,i+1,len) if(c[k]) {
						m+=k; break;
					}

					if(m+a[i]+1<=sum && sum<=m+b[i]-1+(i-1)*(::k-1) ){
						
						ll g=max(a[i]+1,sum-m-(i-1)*(::k-1));
						if(g<=b[i]-1) {
							c[i]=g;	m+=g;
							ForD(k,i-1) {
								c[k] = max(0LL,sum-m-(k-1)*(::k-1));
								m+=c[k];
							}
							upd();
						}					
					}
				}
				else if(a[i]+1>=1){// a[i]!=0
					m+=i;
					if(m+a[i]+1<=sum && sum<=m+b[i]-1+(i-1)*(::k-1) ){
						ll g=max(a[i]+1,sum-m-(i-1)*(::k-1));
						if(g<=b[i]-1) {
							c[i]=g;	m+=g;
							ForD(k,i-1) {
								c[k] = max(0LL,sum-m-(k-1)*(::k-1));
								m+=c[k];
							}
						upd();

						}
					}
				}
			}
		
		}
		
		
		fl3=1;
	}

	ll p1=0;
	ForD(i,len) p1=p1*k+c2[i];
	
	
	return p1;
}

int main()
{
//	freopen("E.in","r",stdin);
//	freopen("e3.out","w",stdout);
	int T=read();
	For(kcase,T) {
		cin>>k>>l>>r;
		get(l,len1,a);
		get(r,len2,b);
		len=max(len1,len2);
		Fork(i,len1+1,len) a[i]=0;
		Fork(i,len2+1,len) b[i]=0;
		ll p1=0,p2=0;
		pk[0]=1;
		For(i,len) pk[i]=pk[i-1]*k;
		ll p0=calc(len);
		clr=0;
		p1=get_mi(len,p0+2);
		printf("Case #%d: %lld %lld %lld\n",kcase,p0, p1,p2=ma);
		
	}
	return 0;
}

你可能感兴趣的:(数位统计DP)