序列 sequence.cpp
阿新 • • 發佈:2018-11-05
【一句話題意】有一個序列,定義f(x)為x在十進位制下的位數,特別地,求對於序列
【分析】先將序列從小到大排序。列舉i點,再二分i點左邊最小的使
進位的點。
時間複雜度
【code】
考場上腦抽寫的,常數大得離譜且非常的醜,但竟然過了。
不想改。。。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define int long long
#define rint register int
using namespace std;
const int maxn=1e6+1000;
int n,a[maxn];
inline void read(int &x){
x=0;char tmp=getchar();
while(tmp<'0'||tmp>'9') tmp=getchar();
while(tmp>='0'&&tmp<='9') x=(x<<1)+(x<<3)+tmp-'0',tmp=getchar();
}
inline int count_num(rint x){
if(x>=10000){
if(x>=1e6){
if(x>=1e8) return 9;
else if(x>=1e7) return 8;
else return 7;
}
else{
if(x>=1e5) return 6;
else return 5;
}
}
else{
if(x>=100){
if(x>=1000) return 4;
return 3;
}
else{
if(x>=10) return 2;
else return 1;
}
}
// rint cnt=0;
// while(x>0) x/=10,cnt++;
// return cnt;
}
inline int ld(rint l,rint r,rint d,rint num){
rint ans,mid;
while(l<=r){
mid=l+r>>1;
if(count_num(a[mid]+num)<d) l=mid+1;
else r=mid-1,ans=mid;
}
return ans;
}
signed main(){
freopen("sequence.in","r",stdin);
freopen("sequence.out","w",stdout);
cin>>n;
for(rint i=1;i<=n;i++)
read(a[i]);
sort(a+1,a+n+1);
int ans=0;
for(rint i=2;i<=n;i++){
int d1=count_num(a[i]+a[i-1]),d2=count_num(a[i]+a[1]),p=i-1;
for(rint j=d1;j>=d2;j--){
ans+=(p-ld(1,p,j,a[i])+1)*j;
p=ld(1,p,j,a[i])-1;
}
}
cout<<ans<<endl;
return 0;
}