Codeforces Round #574 (Div. 2) D2. Submarine in the Rybinsk Sea (hard edition) 【计算贡献】

时间:2023-03-10 03:47:00
Codeforces Round #574 (Div. 2) D2. Submarine in the Rybinsk Sea (hard edition) 【计算贡献】

一、题目

  D2. Submarine in the Rybinsk Sea (hard edition)

二、分析

  相比于简单版本,它的复杂地方在于对于不同长度,可能对每个点的贡献可能是有差异的。

  但是,题目已经说明$a_{i}$最大知道10的9次方,那么$a_{i}$的长度最大也只有10,所以,我们可以按长度进行分组讨论。

  需要注意的是,$a_{i}$确定了在前和在后并且确定了$f(a_{i},b_{i})$中的$b_{i}$的长度后,$a_{i}$对各个位置的贡献其实就确定了,相当于对于每一个$a_{i}$,我们最多求10次贡献就可以了。

三、AC代码

  1 #include <bits/stdc++.h>
2
3 using namespace std;
4 typedef long long ll;
5 const int maxn = 1e5 + 14;
6 const int mod = 998244353;
7 int a[maxn], n;
8
9 int getlen(int data)
10 {
11 int len = 0;
12 while(data)
13 {
14 data/=10;
15 len++;
16 }
17 return len;
18 }
19
20 ll fun1(int x, int a, int b)
21 {
22 vector<int> vec, A(22, 0);
23 while(x)
24 {
25 vec.push_back(x % 10);
26 x /= 10;
27 }
28 reverse(vec.begin(), vec.end());
29 int _len = a + b;
30 if(a >= b)
31 {
32 auto itr = vec.begin();
33 for(int i = 1; i <= a - b + 1; i++)
34 {
35 A[i] = *itr;
36 itr++;
37 }
38 for(int i = a - b + 3; i <= _len; i += 2)
39 {
40 A[i] = *itr;
41 itr++;
42 }
43 }
44 else
45 {
46 auto itr = vec.begin();
47 for(int i = b - a + 1; i <= _len; i += 2)
48 {
49 A[i] = *itr;
50 itr++;
51 }
52 }
53 ll tot = 0;
54 for(int i = 0; i <= _len; i++)
55 {
56 tot = (tot * 10 + A[i]) % mod;
57 }
58 return tot;
59 }
60
61 ll fun2(int x, int b, int a)
62 {
63 vector<int> vec, A(22, 0);
64 while(x)
65 {
66 vec.push_back(x % 10);
67 x /= 10;
68 }
69 reverse(vec.begin(), vec.end());
70 int _len = a + b;
71 if(b <= a)
72 {
73 auto itr = vec.begin();
74 for(int i = 1; i <= a - b; i++)
75 {
76 A[i] = *itr;
77 itr++;
78 }
79 for(int i = a - b + 2; i <= _len; i += 2)
80 {
81 A[i] = *itr;
82 itr++;
83 }
84 }
85 else
86 {
87 auto itr = vec.begin();
88 for(int i = b - a + 2; i <= _len; i += 2)
89 {
90 A[i] = *itr;
91 itr++;
92 }
93 }
94 ll tot = 0;
95 for(int i = 0; i <= _len; i++)
96 {
97 tot = (tot * 10 + A[i]) % mod;
98 }
99 return tot;
100 }
101
102 int main()
103 {
104 while(scanf("%d", &n) != EOF)
105 {
106 ll ans = 0;
107 vector<int> vec[11];
108 for(int i = 0; i < n; i++)
109 {
110 scanf("%d", &a[i]);
111 vec[ getlen( a[i] ) ].push_back(a[i]);
112 }
113 for(int i = 1; i <= 10; i++)
114 {
115 for(auto itr : vec[i])
116 {
117 for(int j = 1; j <= 10; j++)
118 {
119 if( vec[j].size() )
120 {
121 ll res = 0;
122 int len = vec[j].size();
123 res = fun1(itr, i, j);
124 res = (res + fun2(itr, j, i)) % mod;
125 res = res * len % mod;
126 ans = (ans + res) % mod;
127 }
128 }
129 }
130 }
131 printf("%I64d\n", ans);
132 }
133 return 0;
134 }