Автор задачі: | Тунчай Пашаєв |
Підготовлено: | Хасан Салех (MathModel) |
Редагував: | Хасан Салех (MathModel) |
Розв'язок
У нас є масив розміру , масив розміру та ціле число . Перестановка масиву називається красивою, якщо для кожного 1 \le i < m ми маємо b_{p_i} + b_{p_{i+1}} \equiv 0 \pmod{k}. У реалізації нижче ми використовуємо лише той факт, що позицій формують ланцюг довжини ; нам потрібен лише , а не фактичні індекси .
Ми попередньо обчислюємо факторіали та обернені факторіали за модулем 10^9+7 до N = 2\cdot 10^5, і визначаємо
як кількість способів вибрати та впорядкувати елементів з різних.
Для кожного тесту ми читаємо та будуємо:
: кратність точного значення в (для обробки дублікатів),
: кількість елементів з залишком r = x \bmod k.
Потім ми читаємо та ігноруємо його вміст, ми лише зберігаємо .
Якщо m = 1, то жодних обмежень немає, тому кожна перестановка мультимножини є красивою. Кількість різних перестановок дорівнює
реалізовано як fact[n] \cdot \prod_x invfact[\text{cnt}[x]].
Тепер припустимо, що m \ge 2. Лише "спеціальні" позиції обмежені. Якщо якась позиція в ланцюзі має залишок за модулем , сусід по ланцюгу повинен мати залишок
інакше сума не дорівнює за модулем . Таким чином, залишки в ланцюзі формуються з комплементарних пар (r, r_2).
Нехай
Якщо r \neq r_2, то в ланцюзі залишки повинні чергуватися між та r_2. Є два шаблони: почати з (тоді нам потрібно позицій з залишком та з r_2) або почати з r_2 (тоді з r_2 та з ). Якщо \text{rem}[r] = c_0 та \text{rem}[r_2] = c_1, і обидва існують, способи призначити різні елементи на обмежених позицій дорівнюють
Якщо r = r_2 (самокомплементарний залишок, наприклад, r=0 або r=k/2, коли парне), тоді всі обмежених позицій повинні використовувати лише залишок , і якщо є c_0 = \text{rem}[r] таких елементів, кількість способів дорівнює P(c_0,m).
Ми перебираємо всі залишки в , обчислюємо r_2 = (k-r)\bmod k і:
якщо r = r_2, ми використовуємо cur = P(c_0,m);
якщо r < r_2 і r_2 існує, ми використовуємо cur = P(c_0,o)P(c_1,e) + P(c_1,o)P(c_0,e);
якщо r > r_2, ми пропускаємо (невпорядкована пара \{r,r_2\} обробляється, коли ми знаходимося на меншому).
Для кожної такої пари ми маємо способів заповнити обмежених позицій. Залишені n-m позицій вільні і можуть бути заповнені залишковими елементами в будь-якому порядку, додаючи фактор (n-m)!. Таким чином, ми накопичуємо
До цього моменту кожне входження одного й того ж значення розглядається як різний маркований об'єкт. Щоб підрахувати різні перестановки мультимножини , ми ділимо на для кожного різного значення , тобто множимо на invfact[\text{cnt}[x]]. Це те саме виправлення, що й у випадку m=1.
Складність загалом становить \mathcal{O}(\sum n).
MOD=1000000007
MAX=200005
fact=[1]*MAX
invfact=[1]*MAX
for i in range(1,MAX):
fact[i]=fact[i-1]*i%MOD
invfact[i]=pow(fact[i],MOD-2,MOD)
def P(n,r):
if r<0 or r>n:return 0
return fact[n]*invfact[n-r]%MOD
def solve():
n,m,k=map(int,input().split())
rem={}
cnt={}
a=list(map(int,input().split()))
for x in a:
r=x%k
rem[r]=rem.get(r,0)+1
cnt[x]=cnt.get(x,0)+1
input().split()
if m==1:
ans=fact[n]
for c in cnt.values():
ans=ans*invfact[c]%MOD
print(ans)
return
o=(m+1)//2
e=m//2
ans=0
for r,c0 in rem.items():
r2=(k-r)%k
if r==r2:
cur=P(c0,m)
elif r<r2:
if r2 in rem:
c1=rem[r2]
cur=(P(c0,o)*P(c1,e)+P(c1,o)*P(c0,e))%MOD
else:
cur=0
else:
continue
ans=(ans+cur*fact[n-m])%MOD
for c in cnt.values():
ans=ans*invfact[c]%MOD
print(ans)
for _ in range(int(input())):
solve()