找了一场偏水的 ARC 打了打。
20 分钟内干完了 CDE,只剩下 F 了,然后想了一会儿,会了,但是被叫出去叉 c7 中秋联考的 std 去了,回来的时候就已经 VP 结束了,后来 WA 了 114514 发后,终于调完了(虽然下了几发数据)。
C Bugged
简单背包即可。
D Widespread
考虑二分,然后简单 check 一下。
E Meaningful Mean
小套路题,每个数先减 k ,然后就转化为求 (>0) 的子段个数,树状数组维护即可。
F Mirrored
拿到题 :woc ,什么鬼?
想了一会儿 :好像只有 (D mod 9 = 0) 有解?
后来 :我会了!!!
中途出去然后回来后:写完了! WA 了!
WA 了 114514 后 :下了 (inf) 组数据,终于调完了。
首先枚举位数 (l),只要我们确定了前 (leftlceilfrac{l}{2} ight ceil) 位,那么就全部确定了,设 (n_i) 表示 (n) 的第 (i) 位的数,那么我们最后 (rev(n) - n) 则是 :
[sumlimits_{i = 1}^{leftlfloorfrac{l}{2}
ight
floor} (n_i - n_{l - i + 1}) imes (10 ^ {l - i + 1} - 10 ^ i)
]
考虑枚举 (n_i - n_{l - i + 1}) ,使得最后这个柿子为 (D) 即可,这个可以用爆搜,方案简单算一算就行了。
但是很可能会 TLE,考虑减枝:
当还要凑出来的值已经 (>) 之后最大可以凑出来的值 或者 还要凑出来的值已经 (<) 之后最小可以凑出来的值,则 return 0
关于复杂度 :
因为当 (l -1) 后, (10 ^ {l - i + 1} - 10 ^ i) 大概会 (div10) ,那么每次递归下去的有用的叉不会大于 (2) ,因此单次 dfs 复杂度不超过 (mathcal O(2^l))
code:
#include <bits/stdc++.h>
#define in read()
#define rep(i, x, y) for(int i = (x); i <= (y); i++)
#define per(i, x, y) for(int i = (x); i >= (y); i--)
using namespace std;
typedef long long ll;
ll pw[35], mx[35], stk[35], ans, v[35];
int cnt, D;
ll dfs(int x, ll res) {
if(x == cnt + 1) {
if(res == 0) return 1;
return 0;
}
if(res > mx[x] || res < -mx[x]) return 0;
ll t = 0;
rep(i, 0, 9) {
int cho = 10 - i; if(x == 1) cho--;
v[x] = -i;
if(cho > 0) t += dfs(x + 1, res - stk[x] * i) * cho;
cho = 10 - i;
if(i == 0) continue; v[x] = i;
if(cho > 0) t += dfs(x + 1, res + stk[x] * i) * cho;
} return t;
}
int main() {
D = in;
pw[0] = 1; rep(i, 1, 33) pw[i] = pw[i - 1] * 10;
rep(i, 1, 17) {
int l = 0, r = i; cnt = 0;
while(l < r) {
stk[++cnt] = pw[r] - pw[l];
r--; l++;
}
mx[cnt + 1] = 0;
per(j, cnt, 1) mx[j] = mx[j + 1] + stk[j] * 9;
ans += dfs(1, D) * (i & 1 ? 1 : 10);
}
cout << ans << endl;
}