题目链接:B. Power Sequence
题意
给你一个长度为n的序列a,让你通过一些操作使其变成一个叫“power sequence”的序列——存在一个c使得(0≤i≤n-1), a i = c i {a_i=c^i} ai=ci。
- 你能够更改序列里每个元素的位置,这个操作不计入操作数内。
- 你可以选择任意一个元素增加或减少1,每进行一次这个操作,操作数+1。
问最少需要多少操作数使其变为“power squence”。
题解
本题我们先来分析, a i ≤ 1 e 9 , n ≤ 1 e 5 {a_i≤1e9,n≤1e5} ai≤1e9,n≤1e5。
那么我们能得出一个结论,操作数不可能超过 1 e 14 {1e14} 1e14,因为当 a i 全 为 1 e 9 {a_i全为1e9} ai全为1e9,n为 1 e 5 {1e5} 1e5时,我们取c=1就能得到最小值。
然后我们继续分析
当c= 1 0 4 {10^4} 104时,那么power sequence序列为 1 , 1 0 4 , 1 0 8 , 1 0 12 {1,10^4,10^8,10^{12}} 1,104,108,1012
当c= 1 0 3 {10^3} 103时,那么power sequence序列为 1 , 1 0 3 , 1 0 6 , 1 0 9 , 1 0 12 {1,10^3,10^6,10^{9},10^{12}} 1,103,106,109,1012
很容易我们发现当c>=1000时,n不能超过4。如果超过4,我们取c=1时就能得到答案。
所以这道题我们可以枚举c。由于 a i ≤ 1 e 9 , n ≥ 3 {a_i≤1e9,n≥3} ai≤1e9,n≥3,所以 c ≤ 1 e 9 {c≤\sqrt{1e9}} c≤1e9。
在计算power sequence的 a i {a_i} ai时,如果 a i ≥ 1 e 14 {a_i≥1e14} ai≥1e14,就退出循环。
由于有剪枝,时间复杂度不会超。
代码
#include<iostream>
#include <sstream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double ld;
//typedef int fuck;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define lowbit(x) x&-x
//#define int long long
const double PI=acos(-1.0);
const double eps=1e-6;
//const ll mod=1e9+7;
const ll inf=1e18;
const int maxn=1e5+10;
const int maxm=100+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
ll a[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%lld",&a[i]);
sort(a,a+n);
ll ans=inf;
for(ll c=1;c<=sqrt(1e9)+1;c++)
{
ll tmp=0,tt=1;
int flag=1;
for(int i=0;i<n;i++)
{
if(tt>=1e14) {
flag=0;break;}
tmp+=abs(a[i]-tt);
tt*=c;
}
if(flag) ans=min(ans,tmp);
}
printf("%lld\n",ans);
}