1 条题解
-
0
思路与算法
设D=Σ(i=1..n)digits(i)。按展开系数的子集分别统计a字符、下标数字、系数内部加号、括号、外部加号及x的指数。二项式恒等式ΣkC(n,k)=n2^(n-1)、每个下标出现2^(n-1)次,将总长度化简为(n+D)2^(n-1)+2^n+3n+D-4。D按1位、2位等连续区间计数,幂用模10000快速幂。
正确性说明
选k个a的每个子集恰是一项系数单项式;每个a_i在全体子集中出现一半。中间系数有括号,常数系数只有一个乘积不加括号;x的一次项不写指数,零次项不写x。逐类统计与样例所用格式一致,化简公式因此精确。
复杂度
D分位数区间求和O(log10n),两次幂O(logn),时间O(logn),额外空间O(1)。所有初始化常数;n≤1e9,64位中间值足够。
易错点
长度不计展示用的乘号或上标排版命令,只计题面所列字符及指数、下标数字。n=1时公式也得到x+a1长度4。模10000不是质数,直接二进制幂无需费马降幂。
参考代码(C++11)
#include <bits/stdc++.h> using namespace std; long long pw(long long a, long long n) { long long r = 1; while (n) { if (n & 1) r = r * a % 10000; a = a * a % 10000; n >>= 1; } return r; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); long long n; cin >> n; long long d = 0; for (long long p = 1, len = 1; p <= n; p *= 10, len++) d += (min(n, p * 10 - 1) - p + 1) * len; long long ans = ((n + d) % 10000 * pw(2, n - 1) + pw(2, n) + 3 * n + d - 4) % 10000; cout << ans << '\n'; }
- 1