Автор проблеми: | Хасан Салех (MathModel) |
Підготовлено: | Хасан Салех (MathModel) |
Редагував: | Хасан Салех (MathModel) |
Рішення
Нам дано рядок з цифр довжини . Для кожної позиції ми фіксуємо s_i на позиції і переставляємо решту n-1 цифр. Ми розглядаємо лише відмінні перестановки і визначаємо:
Ключова ідея
Замість того, щоб безпосередньо підсумовувати цілі числа, ми підсумовуємо внески за позицією. Все зводиться до підрахунку перестановок мультимножин.
1) Основні факти
Нехай кількість цифр буде c_0,\dots,c_9.
Кількість відмінних перестановок цифр:
Десяткові ваги: позиція (нумерація зліва) має вагу
Визначимо
Отже, сума ваг усіх позицій, окрім , дорівнює
2) Фіксація однієї позиції
Зафіксуємо індекс і нехай
Видалимо цю цифру з мультимножини.
Внесок фіксованої позиції
Цифра завжди знаходиться на позиції . Залишені n-1 цифри можуть бути переставлені в
способів.
Отже, внесок фіксованої позиції дорівнює
Внесок інших позицій
Тепер розглянемо залишені n-1 позиції.
Виберемо значення цифри , яке ще доступне. Якщо ми помістимо в одну конкретну іншу позицію, залишені цифри можуть бути переставлені в
способів.
Це число не залежить від того, яку позицію ми вибираємо. Отже, підсумовуючи по всіх інших позиціях, ми просто множимо на суму їх ваг:
Таким чином, загальний внесок цифри по всіх інших позиціях дорівнює
Підсумовуючи по всіх j=0\dots9, отримуємо повний внесок незакріплених позицій.
3) Остаточна формула
Збираючи все разом:
Це обчислюється незалежно для кожного .
4) Складність
Цифри варіюються лише від до , тому всі ділення факторіалів відбуваються над мультимножиною постійного розміру. Для кожної позиції ми перебираємо цифри .
Загальна складність: .
з невеликим константним фактором.
Реалізація
mod=10**9+7
mx=10**6+5
pw=[0]*mx
fc=[0]*mx
iv=[0]*mx
c=[0]*10
def solve():
s=input().strip()
n=len(s)
for i in range(10):c[i]=0
for x in s:c[int(x)]+=1
tp=0
for i in range(n):tp=(tp+pw[i])%mod
for i in range(n):
v=int(s[i])
tp2=(tp-pw[n-i-1])%mod
c[v]-=1
w=fc[n-1]
for k in range(10):w=w*iv[c[k]]%mod
ans=pw[n-i-1]*w%mod*v%mod
for j in range(1,10):
c[j]-=1
w2=fc[n-2]
for k in range(10):w2=w2*iv[c[k]]%mod
c[j]+=1
ans=(ans+w2*tp2%mod*j)%mod
c[v]+=1
print(ans,end=' ')
print()
pw[0]=fc[0]=iv[0]=1
for i in range(1,1000001):
pw[i]=pw[i-1]*10%mod
fc[i]=fc[i-1]*i%mod
iv[i]=pow(fc[i],mod-2,mod)
for _ in range(int(input())):solve()