Codeforces Round #574 (Div. 2) D2Submarine in the Rybinsk Sea (hard edition)

it2022-05-05  184

题目链接

This problem differs from the previous one only in the absence of the constraint on the equal length of all numbers a1,a2,…,an.

A team of SIS students is going to make a trip on a submarine. Their target is an ancient treasure in a sunken ship lying on the bottom of the Great Rybinsk sea. Unfortunately, the students don’t know the coordinates of the ship, so they asked Meshanya (who is a hereditary mage) to help them. He agreed to help them, but only if they solve his problem.

Let’s denote a function that alternates digits of two numbers f(a1a2…ap−1ap,b1b2…bq−1bq), where a1…ap and b1…bq are digits of two integers written in the decimal notation without leading zeros.

In other words, the function f(x,y) alternately shuffles the digits of the numbers x and y by writing them from the lowest digits to the older ones, starting with the number y. The result of the function is also built from right to left (that is, from the lower digits to the older ones). If the digits of one of the arguments have ended, then the remaining digits of the other argument are written out. Familiarize with examples and formal definitions of the function below.

For example: f(1111,2222)=12121212 f(7777,888)=7787878 f(33,44444)=4443434 f(555,6)=5556 f(111,2222)=2121212 Formally,

if p≥q then f(a1…ap,b1…bq)=a1a2…ap−q+1b1ap−q+2b2…ap−1bq−1apbq; if p<q then f(a1…ap,b1…bq)=b1b2…bq−pa1bq−p+1a2…ap−1bq−1apbq. Mishanya gives you an array consisting of n integers ai, your task is to help students to calculate ∑ni=1∑nj=1f(ai,aj) modulo 998244353.

Input The first line of the input contains a single integer n (1≤n≤100000) — the number of elements in the array. The second line of the input contains n integers a1,a2,…,an (1≤ai≤109) — the elements of the array.

Output Print the answer modulo 998244353.

Example1:

3 12 3 45 12330

Example2:

2 123 456 1115598

题意: 大致意思就是,一个函数 f(x,y) 计算的是,先从y开始,取y的最后一位,该值为初值,舍掉,再取x的最后一位,放到初值的左侧,再舍掉,一直循环直到有一个数字为0,把另外一个数字的全部剩余数字放到值的左侧,构成一个新的数,求:

sum=0; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ sum+=f(arr[i],arr[j]); } } sum%=mod;

思路: 某一个数a[i]在执行题目描述中的操作时,实际上是把自己的每一位数字分离出来 然后乘上当前所在位置的指数的幂(ps:指数每次增长2) 因为数字a[i]与相同位数的数字操作时,位置相同 与不同位数的数字操作时,位置不同 数字最大长度为10位 所以可以遍历所有n个数字 每个数字对每一个位数的数字运算的结果乘以总共多少个这么长的数字 求和取模即可

代码1:

#include <bits/stdc++.h> using namespace std; #define MOD 998244353 int n, a[100005], cnt[15]; long long ans, po[30]; int main() { po[0] = 1; for (int i = 1; i < 30; i++) po[i] = po[i - 1] * 10 % MOD; scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%d", a + i); cnt[to_string(a[i]).size()]++; } for (int i = 0; i < n; i++) { //代码原理 //某一个数a[i]在执行题目描述中的操作时,实际上是把自己的每一位数字分离出来 //然后乘上当前所在位置的指数的幂(ps:指数每次增长2) //因为数字a[i]与相同位数的数字操作时,位置相同 //与不同位数的数字操作时,位置不同 //数字最大长度为10位 //所以可以遍历所有n个数字 //每个数字对每一个位数的数字运算的结果乘以总共多少个这么长的数字 //求和取模即可 string s = to_string(a[i]); for (auto& j : s) j -= '0'; for (int j = 1; j <= 10; j++) { long long sum = 0; for (int k = s.size() - 1, at = 0, left = j; k >= 0; k--, at++) { if (left) { at++; left--; } sum += po[at] * s[k]; } for (int k = s.size() - 1, at = 0, left = j; k >= 0; k--, at++) { sum += po[at] * s[k]; if (left) { at++; left--; } } (ans += sum % MOD * cnt[j]) %= MOD; } } printf("%lld\n", ans); }

代码2:

#include<bits/stdc++.h> using namespace std; const int mod = 998244353; int n; typedef long long ll; ll arr[110000]; ll po[30]; int len[20]; int countLength(ll num) { int res = 0; while (num) { res++; num /= 10; } return res; } int main() { po[0] = 1; for (int i = 1; i < 30; i++) { po[i] = po[i - 1] * 10 % mod; } scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%lld", arr + i); } for (int i = 0; i < n; i++) { len[countLength(arr[i])]++; } ll res = 0; int k, ind, length; for (int i = 0; i < n; i++) { ll t; int llen = countLength(arr[i]); for (int j = 1; j <= 10; j++) { ll sum = 0; t = arr[i]; for (length = j, ind = 0; t; ind++, t /= 10) { sum += po[ind] * (t % 10); if (length) { ind++; length--; } } t = arr[i]; for (length = j, k = 0, ind = 0; t; ind++, t /= 10) { if (length) { ind++; length--; } sum += po[ind] * (t % 10); } res += (sum%mod*len[j]) % mod; res %= mod; } } printf("%lld", res); return 0; }

最新回复(0)