Codeforces Round #574 (Div. 2) D1&D2(数论 + 组合数学)

time limit per test: 2 seconds

memory limit per test: 256 megabytes

input: standard input

output: standard output

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

Mishanya gives you an array consisting of nintegers 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.

Examples

Input

3
12 3 45

Output

12330

Input

2
123 456

Output

1115598

题解:

做了D1后,再做D2会带着惯性思维,其实对于不同的长度的数分情况讨论即可。

1. 首先需要预处理一个前缀和lens,后面会用到,lens[i]表示长为i的数的个数。

2. 对于一个数ai,从它的最低位数字开始考虑。ai从最低位开始的第j个数字记为aij,则aij最后对答案的贡献分三种情况考虑:

    (1) 对于所有长度大于j的数ak,那么ai在与ak组合之后,aij可以出现在第j*2和j*2-1位,因此除去与自己的组合,该部分对最后答案的贡献为C(lens[INF]-lens[j-1]-1, 1)*aij*[10^(j*2) + 10^(j*2-1)];

    (2) 对于所有长度等于j的数ak,那么ai在与ak组合之后, ai长度超过ak的部分需要“堆”在两个数的前j位数字组合后的数前面,故该部分对最后答案的贡献位floor(ai / (10^j)) * 10^(j * 2)*2;

    (3) 对于ai与自己组合情况,贡献为aij*[10^(j*2) + 10^(j*2-1)]。

3. 对每个数的每位数字按照1, 2的方法进行处理,将所有的贡献,累加便得到答案。

其实2中的(1)和(3)可以合在一起算,这里为方便理解就分开写了。需要注意的是计算的过程中要记住适当的进行模运算,防止溢出。

代码如下:

#include
#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const int maxn = 1e5 + 5;
ll a[maxn];
const ll mod = 998244353;
ll tens[20];
ll lens[20];
int main()
{
    tens[0] = 1;
    for(int i = 1; i < 20; ++i)
    {
        tens[i] = ((tens[i - 1] % mod) * 10) % mod;
    }
    int n;
    memset(lens, 0, sizeof(lens));
    ll sum = 0;
    scanf("%d", &n);
    for (int i = 0; i < n; ++i)
    {
        scanf("%I64d", &a[i]);
        int tp = a[i];
        int cal = 0;
        while(tp)
        {
            cal++;
            tp /= 10;
        }
        lens[cal]++;
    }
    for(int i = 1;i < 20; ++i)
    {
        lens[i] += lens[i - 1];
    }
    for(int i = 0;i < n; ++i)
    {
        int cal = 0;
        ll temp = sum;
        while(a[i])
        {
            ll tp = a[i] % 10;
            a[i] /= 10;
            
            // for the longer ones
            ll num_long = lens[19] - lens[cal / 2];
            sum = sum + ((tp * ((tens[cal] + tens[cal + 1]) % mod)) % mod) * (num_long - 1) % mod;

            // for the shorter ones
            ll num_equal= lens[cal / 2 + 1] - lens[cal / 2] ;
            sum = (sum +(a[i] * tens[cal + 2] % mod) * num_equal * 2 % mod) % mod;

            // for self
            sum = sum + (tp * ((tens[cal] + tens[cal + 1]) % mod)) ;
            sum %= mod;
            cal += 2;
        }
    }
    printf("%I64d\n", sum);
    return 0;
}

 

你可能感兴趣的:(数学相关)