序列 sequence.cpp

版权声明:写得不好,随便转载,但请注明出处,感激不尽 https://blog.csdn.net/xyc1719/article/details/83623381

【一句话题意】有一个序列,定义f(x)为x在十进制下的位数,特别地,求对于序列 Σ 1 i < j n f ( a i + a j ) \Sigma_{1≤i<j≤n}f(a_i+a_j)
【分析】先将序列从小到大排序。枚举i点,再二分i点左边最小的使 a i a_i 进位的点。
时间复杂度 O ( n l o g 2 n ) O(nlog_2n)
【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;
}

猜你喜欢

转载自blog.csdn.net/xyc1719/article/details/83623381
今日推荐