首页 > 其他分享 >ARC158C All Pair Digit Sums 题解

ARC158C All Pair Digit Sums 题解

时间:2023-03-12 22:47:58浏览次数:53  
标签:10 int 题解 ARC158C vec res Pair 进位 define

题目链接

题意

设 \(f(x)\) 表示 \(x\) 的各位之和。例如 \(f(158)=1+5+8=14,f(2023)=2+0+2+3=7,f(1)=1\) 等。

给定一个正整数序列 \(A=(A_1,...,A_N)\),求 \(\sum_{i=1}^N\sum_{j=1}^Nf(A_i+A_j)\)。

数据范围:\(1\le N\le 2\times 10^5,1\le A_i<10^{15}\)。

题解

这题思路非常自然,先计算出如果每次加法都没有进位,即若 \(f(A+B)=f(A)+f(B)\) 时的答案,为 \(2N\sum_{i=1}^Nf(A_i)\)。

考虑到每次加法进位都会使答案 \(-9\),则只要统计有多少次进位即可。

从低到高地枚举每一位的进位,设当前为第 \(k\) 位,则在这一位进位的条件就是 \(A_i\bmod 10^{k+1}+A_j\bmod 10^{k+1}\ge 10^{k+1}\)。

那么取 \(x_i=A_i\bmod 10^{k+1}\),对 \(x_i\) 进行排序,然后用二分或者 two pointers 即可。

时间复杂度为 \(O(KN\log N)\) 或 \(O(KN)\),其中 \(K\) 为位数。

反思

赛时想这道题时,没有想到这个直接判断 \(\ge 10^{k+1}\),而是把每一位拆开来看,看前面连续的和为 \(9\) 的进位。这样拆开使得计算冗杂,并且不好维护。

所以要换个角度再看一看问题。

代码

//none
#include<bits/stdc++.h>
#define int long long
#define ll long long
#define rep(i,n) for(int i=0;i<n;i++)
#define rept(i,n) for(int i=1;i<=n;i++)
#define repe(i,l,r) for(int i=l;i<=r;i++)
#define FOR(i,r,l) for(int i=r;i>=l;i--)
#define fi first
#define se second
#define pii pair<int,int>
#define mpr make_pair
#define pb push_back
#define sz(v) (int)(v.size())
using namespace std;
int read(){int sum=0,f=1;char c;c=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){sum=(sum<<1)+(sum<<3)+(c-'0');c=getchar();}return sum*f;}
void out(int x){if(x<0){x=-x;putchar('-');}if(x>=10)out(x/10);putchar(x%10+'0');}
int fast(int a,int b,int P){int res=1;if(P<=0){while(b){if(b&1)res=res*a;a=a*a;b>>=1;}}else{while(b){if(b&1)res=res*a%P;a=a*a%P;b>>=1;}}return res;}
template<typename T>void chmax(T& a,T b){if(a<b)a=b;return;}
template<typename T>void chmin(T& a,T b){if(a>b)a=b;return;}
const int N=2e5+5;
int n,a[N],b[N][15],cur[N];
signed main(){
	n=read();
	int ans=0;
	rept(i,n){
		a[i]=read();
		rep(j,15){
			b[i][j]=a[i]%10;
			ans+=2*n*b[i][j];
			a[i]/=10;
		}
	}
	vector<int> vec;
	rep(i,15){
		vec.clear();
		rept(j,n){
			cur[j]+=b[j][i]*fast(10,i,0);
			vec.pb(cur[j]);
		}
		sort(vec.begin(),vec.end());
		rep(j,n){
			int pos=lower_bound(vec.begin(),vec.end(),fast(10,i+1,0)-vec[j])-vec.begin();
			ans-=(sz(vec)-pos)*9;
		}
	}
	out(ans);
	return 0;
}

标签:10,int,题解,ARC158C,vec,res,Pair,进位,define
From: https://www.cnblogs.com/Jerry-Jiang/p/17209408.html

相关文章

  • 题解 ARC111B【Reversible Cards】
    我们将值域中每个数视作一个节点,将每张卡片视作连接两个节点的边,则问题转化为:对于每条边都选择一个端点,使得被选择的节点总数最大。显然每个连通块可以分开处理。设连通块......
  • 【题解】CF364D
    题目大意给定集合a,求最大的是大小超过一半的子集的最大公约数的数是什么。题解“超过一半”即想到随机化n次后只有\(\frac{1}{2^n}\)的几率错误,于是随机一个数判断它的......
  • 题解 P3306 [SDOI2013] 随机数生成器
    Link它\(p\)都是质数了,这不就明示我们是bsgs了吗我没看出来然后我们来倒一下\(n\)天的式子第一天是\(x_1\),第二天是\(ax_1+b\),第三天是\(a^2x_1+(ab+b)\),第四......
  • 【题解】CF1264D2
    题目大意给定一个长度为\(n\)的字符串,其中只有(,),?三种字符,其中?可以为(或者)对于一个括号序列,定义其权值为其通过删除字符后可以得到的合法的括号匹配的最深的深度,下......
  • pairwise损失_triplet损失_提升精排模型的trick
    多标签importtorchimporttorch.nnasnnimporttorch.optimasoptimclassRankModel(nn.Module):def__init__(self,num_features):super(RankMode......
  • AcWing 199. 余数之和 题解
    做了一下午……题解都看不懂,最后自己比比划划弄懂了。题意:给出\(n,k\),求\(\sum\limits_{i=1}^nk\modi\)。首先取模形式十分不好处理,所以我们可以根据取模运算定义做......
  • windows 文件夹打开默认是小窗口问题解决
    目录windows文件夹打开默认是小窗口问题解决问题解决windows文件夹打开默认是小窗口问题解决不知道误操作了什么,最近点击windows文件夹默认打开的都是小窗口,每次需要点......
  • 3 月 8 日测试题解
    3月8日测试题解T1题意给你一张图\(G=(V,E)\),\(|V|=n\),\(|E|=m\),带边权、点权。你可以执行以下操作任意多次:选取一个顶点,将其自身与与其相连的边删去当你......
  • 2023.3.12 模拟赛题解
    天黑黑题意大致:给出含\(\max\)和\(+\)的表达式以及其中的\(n\)个数,求其最大值。用前缀表达式的形式给出,X表示一个要填的数,B表示\(\max\),A表示\(+\)。题解......
  • CF915E 题解(动态开点线段树)
    题目传送门简要题意:题面就挺简要的。看到题目第一眼想到线段树,再看一眼数据范围,\(1≤n≤10^9\),寄,既然不能直接用线段树,那怎么办呢?可以离散化,为了避免麻烦的离散化,......