SCU 4437 Carries
二分。
先看个位上会发生几次进位,把每个数对$10$取余后排序,对每个数寻找有个数字和他相加会大于$10$,就有几次进位。然后继续处理十位,百位......
#include<bits/stdc++.h> using namespace std; int n; long long x[100010],b[100010]; int main() { while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) scanf("%lld",&x[i]); long long ans=0; for(long long now=10;now<=1000000000;now*=10) { for(int i=1;i<=n;i++) b[i] = x[i]%now; sort(b+1,b+1+n); for(int i=1;i<=n;i++) { int L=i+1,R=n,pos=-1; while(L<=R) { int mid = (L+R)/2; if(b[mid]+b[i]>=now) pos=mid,R=mid-1; else L=mid+1; } if(pos==-1) continue; ans=ans+n-pos+1; } } printf("%lld\n",ans); } return 0; }