ARC136-D 无脑翻译壬
(翻译官方题解)
定义:对于 \(\lt 10^6\) 的整数 \(x\) , \(y\) ,将不足 \(10^6\) 的数用前导 \(0\) 补全,若对于 \(x\) 的每一位上的数字 \(N_{x,i}\,,i \in [1,5]\) ,都有 \(N_{x,i} \ge N_{y,i}\) ,则称 \(x\) 支配 \(y\) ,记作 \(x \bigsqcup y\) (?).
那么按位 \(x+y\) 不进位当且仅当 \((10^6-1-x) \bigsqcup y\)
所以问题转化为,对于每个 \(A_i\) ,求得它能支配多少序列中的其它数
伟大的 \(Editorial\) 非常不屑地说,这个东西在二进制下就是快速 \(ζ\) 变换的裸题(
但是我们不会啊?而且这是十进制
所以伟大的 \(Editorial\) 又说,十进制下的实现就是 \(Dp\) .
设 \(f_x\) 为 \(x\) 能支配的 \(A_i\) 个数,于是有
\[f_x=\sum_{j=0}^{\lfloor lg\,x \rfloor}(f_x-10^j,if\;N_{i,j} \ne 0)
\]
然后刷表填表都行, \(dp\) 递推一下就行
注意如果一个数 \(A_i\) 满足 \((10^6-1-A_i)\bigsqcup A_i\) ,答案就会多出一组 \((i,i)\) ,减掉就行
注意输入输出一定要用 \(template\) (捂脸
改了答案类型不改输出传参类型是屑
#include <cstring>
#include <cmath>
#include <bitset>
#include <algorithm>
using namespace std;
#define ri register int
#define ll long long
#define N 1000002
#define Tp template<typename T>
Tp inline void in(T &a){
a=0; register char in=getchar();
while(!isdigit(in)) in=getchar();
while(isdigit(in)) a=(a<<3)+(a<<1)+(in^48),in=getchar();
} //all positive nums
Tp inline void out(T a){
if(a<0) putchar('-'),a=-a;
if(a>=10) out(a/10);
putchar(a%10+48);
}
int n,a[N];
int zeta[N];
inline int pow10(int a){
ri ret(1);
while(a--) ret=(ret<<3)+(ret<<1);
return ret;
}
static const int lim=pow10(6)-1;
inline void done(){
ri t=1;
for(ri i(0);i<=5;++i){
for(ri j(0);j<=lim;++j)
if(((j/t)%10)!=9) zeta[j+t]+=zeta[j];
t=(t<<3)+(t<<1);
}
}
bitset<N> flg;
inline bool check(int x){
while(x){
if(x%10>=5) return false;
x/=10;
} return true;
}
int main()
{
in(n);
for(ri i=1;i<=n;++i){
in(a[i]),++zeta[a[i]];
flg[i]=check(a[i]);
}
done();
register ll ans(0);
for(ri i=1;i<=n;++i)
ans+=zeta[lim-a[i]]-flg[i];
out(ans>>1);
return 0;
}
附录:
- 反思
分析出来什么东西一定要多检查几遍
对于这个转换成值域问题分析其实还是不慢(雾
但是由于科技不行,被橄榄了(
当时在想二维值域树状数组
但是发现分析有一步挂了……
而且我不会打二维树状数组
- 关于快速 \(\zeta\) 变换
l1nk
暂时 没看懂,待补(咕
(抄下来晚自习看)
update:
我焯,有人用六维前缀和艹过去了……