$$ \newcommand{\seq}[2]{{#1}_{1},{#1}_{2},\cdots,{#1}_{#2}} \newcommand{\num}[1]{1,2,\cdots,#1} \newcommand{\stra}[2]{\begin{bmatrix}#1 \\ #2\end{bmatrix}} \newcommand{\strb}[2]{\begin{Bmatrix}#1 \\ #2\end{Bmatrix}} \newcommand{\dw}[1]{\underline{#1}} \newcommand{\up}[1]{\overline{#1}} $$

Codeforces 991

991 F

题意

给一个 \(\le 10^{10}\) 的正整数,使用'0'~'9','+','*','^'//乘方字符表示这个数。求表示方法所形成的字符串长度最小的一种。

Examples

Input
2018
Output
2018
Input
1000000007
Output
10^9+7
Input
10000000000
Output
100^5
Input
2000000000
Output
2*10^9

首先,仅用'+','*'不能减小长度。
其次,乘方的底数必然 \(\le \sqrt{n}\)
再次,所有的数最多只能表示为 \(a^b*c^d+e^f\) 的形式。
于是,brute force枚举所有情况即可。中间可以用一些小小的优化,如二分。
复杂度\(O(玄学)≈O(\sqrt{n}\log n)\)

Code

#include<bits/stdc++.h>
#define INF 1050000000
using namespace std;
typedef long long D;
D n;
D len(D a){
	if(!a)return 1;
	D ret=0;
	while(a)ret++,a/=10;
	return ret;
} 
struct data{
	D a,b,c,d,e,f,val,l; //a^b*c^f+d^e
	data():c(1),d(0),e(1),f(1){}
	data(D _a,D _b,D _val):a(_a),b(_b),c(1),d(0),e(1),f(1),val(_val){}
	bool operator <(const data& dat)const{
		return val==dat.val?l<dat.l:val<dat.val;
	}
	void calc(){
		l=len(a)+len(b)+len(c)+len(d)+len(e)+len(f)+5;
		if(b==1)l-=2;
		if(c==1)l-=2;
		if(d==0)l-=2;
		if(e==1)l-=2;
		if(f==1)l-=2;
	}
}a[1000000],b[1000000];
D cnt;
int main(){
	cin>>n;
	a[++cnt]=data(n,1,n);
	a[cnt].calc();
	b[cnt]=a[cnt];
	for(D i=2;i*i<=n;i++){
		for(D j=i,k=1;j<=n;j*=i,k++){
			a[++cnt]=data(i,k,j);
			a[cnt].c=n/a[cnt].val;
			a[cnt].d=n-a[cnt].val*a[cnt].c;
			a[cnt].calc();
			b[cnt]=a[cnt];
		}
	}
	sort(b+1,b+cnt+1);
	for(D i=1;i<=min(cnt,10000ll);i++){
		for(D j=1;j<=100;j++){
			D l=1,r=cnt,mid,ans=-1;
			while(l<=r){
				mid=(l+r)>>1;
				if(a[i].val*j+b[mid].val==n)ans=mid,r=mid-1;
				else if(a[i].val*j+b[mid].val<n)l=mid+1;
				else r=mid-1;
			}
			if(ans!=-1){
				a[++cnt]=a[i];
				a[cnt].c=j;
				a[cnt].d=b[ans].a;
				a[cnt].e=b[ans].b;
				a[cnt].calc();
			}
		}
	}
	for(D i=1;i<=min(cnt,500000ll);i++){
		D l=1,r=cnt,mid,ans=-1;
		while(l<=r){
			mid=(l+r)>>1;
			if(a[i].val*b[mid].val<=n)ans=mid,l=mid+1;
			else r=mid-1;
		}
		if(ans!=-1){
			a[++cnt].a=a[i].a;
			a[cnt].b=a[i].b;
			a[cnt].c=b[ans].a;
			a[cnt].f=b[ans].b;
			a[cnt].d=n-a[i].val*b[ans].val;
			a[cnt].calc();
		}
	}
	int minn=INF,mini;
	for(D i=1;i<=cnt;i++){
		if(a[i].l<minn){
			minn=a[i].l;
			mini=i;
		}
	}
	cout<<a[mini].a;
	if(a[mini].b!=1)cout<<"^"<<a[mini].b;
	if(a[mini].c!=1)cout<<"*"<<a[mini].c;
	if(a[mini].f!=1)cout<<"^"<<a[mini].f;
	if(a[mini].d!=0)cout<<"+"<<a[mini].d;
	if(a[mini].e!=1)cout<<"^"<<a[mini].e;
	return 0;
}
posted @ 2019-01-26 11:38  chc_1234567890  阅读(223)  评论(0编辑  收藏  举报