版权声明:写得不好,随便转载,但请注明出处,感激不尽 https://blog.csdn.net/xyc1719/article/details/83623381
【一句话题意】有一个序列,定义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;
}