3123 - summy: Difference between revisions
Pagină nouă: == Cerința == Se dau n şi k numere naturale. Calculați suma ∑ni=1ik. == Date de intrare == Se dau n şi k numere naturale. Calculați suma ∑ni=1ik. == Date de ieșire == Programul va afișa pe ecran valoarea sumei ∑ni=1ik, modulo 1.000.000.007. == Restricții și precizări == ~ 1 ≤ n ≤ 100.000 şi 1 ≤ k ≤ 1.000.000.000 pentru 70% din teste <br> ~ 1 ≤ n ≤ 1.000.000.000 şi 1 ≤ k ≤ 100.000 pentru 30% din teste == Exemplu 1 == ; Intrare : 5 3 ; Ieșire... |
No edit summary |
||
(One intermediate revision by the same user not shown) | |||
Line 6: | Line 6: | ||
Programul va afișa pe ecran valoarea sumei ∑ni=1ik, modulo 1.000.000.007. | Programul va afișa pe ecran valoarea sumei ∑ni=1ik, modulo 1.000.000.007. | ||
== Restricții și precizări == | == Restricții și precizări == | ||
*1 ≤ n ≤ 100.000 şi 1 ≤ k ≤ 1.000.000.000 pentru 70% din teste | |||
*1 ≤ n ≤ 1.000.000.000 şi 1 ≤ k ≤ 100.000 pentru 30% din teste | |||
= Exemplul 1: = | |||
Intrare | |||
5 3 | |||
Ieșire | |||
225 | |||
= Exemplul 2: = | |||
Intrare | |||
5 3 | |||
Ieșire | |||
7 8 | |||
7907396 | |||
== Rezolvare == | |||
<syntaxhighlight lang="python" line="1"> | |||
MOD = 1000000007 | |||
def gcd(a, b): | |||
if b == 0: | |||
return (1, 0) | |||
else: | |||
x, y = gcd(b, a % b) | |||
return (y, x - y * (a // b)) | |||
def invers(x): | |||
inv, _ = gcd(x, MOD) | |||
if inv <= 0: | |||
inv = MOD + inv % MOD | |||
return inv | |||
def pu(b, e): | |||
if e == 0: | |||
return 1 | |||
elif e % 2 == 0: | |||
x = pu(b, e // 2) | |||
return (x * x) % MOD | |||
else: | |||
return (b * pu(b, e - 1)) % MOD | |||
def calculate_for_small_n(n, k): | |||
sol = 0 | |||
for i in range(1, n + 1): | |||
sol = (sol + pu(i, k)) % MOD | |||
return sol | |||
def verifica_restrictii(n, k): | |||
return 1 <= n <= 100000 and 1 <= k <= 1000000000 | |||
def main(): | |||
n, k = map(int, input().split()) | |||
if verifica_restrictii(n, k): | |||
if n <= 100000: | |||
print(calculate_for_small_n(n, k)) | |||
else: | |||
suma = 1 | |||
numarator = 1 | |||
numitor = 1 | |||
for i in range(2, k + 3): | |||
numarator = (numarator * (n - i)) % MOD | |||
numitor = (numitor * (1 - i)) % MOD | |||
if numitor < 0: | |||
numitor += MOD | |||
sol = (numarator * invers(numitor)) % MOD | |||
for i in range(2, k + 3): | |||
suma = (suma + pu(i, k)) % MOD | |||
numarator = (numarator * (n - i + 1)) % MOD | |||
numarator = (numarator * invers(n - i)) % MOD | |||
numitor = (numitor * (i - 1)) % MOD | |||
numitor = (-numitor * invers(k + 3 - i)) % MOD | |||
if numitor < 0: | |||
numitor += MOD | |||
y = (numarator * invers(numitor)) % MOD | |||
sol = (sol + suma * y) % MOD | |||
print(sol) | |||
else: | |||
print("Datele nu corespund restrictiilor impuse") | |||
if __name__ == "__main__": | |||
main() | |||
</syntaxhighlight> | </syntaxhighlight> | ||
== Explicatie == | |||
∑5i=1i*3=1**3+2**3+3**3+4**3+5**3=225 |
Latest revision as of 16:52, 18 May 2024
Cerința[edit | edit source]
Se dau n şi k numere naturale. Calculați suma ∑ni=1ik.
Date de intrare[edit | edit source]
Se dau n şi k numere naturale. Calculați suma ∑ni=1ik.
Date de ieșire[edit | edit source]
Programul va afișa pe ecran valoarea sumei ∑ni=1ik, modulo 1.000.000.007.
Restricții și precizări[edit | edit source]
- 1 ≤ n ≤ 100.000 şi 1 ≤ k ≤ 1.000.000.000 pentru 70% din teste
- 1 ≤ n ≤ 1.000.000.000 şi 1 ≤ k ≤ 100.000 pentru 30% din teste
Exemplul 1:[edit | edit source]
Intrare
5 3
Ieșire
225
Exemplul 2:[edit | edit source]
Intrare
5 3
Ieșire
7 8 7907396
Rezolvare[edit | edit source]
<syntaxhighlight lang="python" line="1"> MOD = 1000000007
def gcd(a, b):
if b == 0: return (1, 0) else: x, y = gcd(b, a % b) return (y, x - y * (a // b))
def invers(x):
inv, _ = gcd(x, MOD) if inv <= 0: inv = MOD + inv % MOD return inv
def pu(b, e):
if e == 0: return 1 elif e % 2 == 0: x = pu(b, e // 2) return (x * x) % MOD else: return (b * pu(b, e - 1)) % MOD
def calculate_for_small_n(n, k):
sol = 0 for i in range(1, n + 1): sol = (sol + pu(i, k)) % MOD return sol
def verifica_restrictii(n, k):
return 1 <= n <= 100000 and 1 <= k <= 1000000000
def main():
n, k = map(int, input().split()) if verifica_restrictii(n, k): if n <= 100000: print(calculate_for_small_n(n, k)) else: suma = 1 numarator = 1 numitor = 1 for i in range(2, k + 3): numarator = (numarator * (n - i)) % MOD numitor = (numitor * (1 - i)) % MOD if numitor < 0: numitor += MOD sol = (numarator * invers(numitor)) % MOD for i in range(2, k + 3): suma = (suma + pu(i, k)) % MOD numarator = (numarator * (n - i + 1)) % MOD numarator = (numarator * invers(n - i)) % MOD numitor = (numitor * (i - 1)) % MOD numitor = (-numitor * invers(k + 3 - i)) % MOD if numitor < 0: numitor += MOD y = (numarator * invers(numitor)) % MOD sol = (sol + suma * y) % MOD print(sol) else: print("Datele nu corespund restrictiilor impuse")
if __name__ == "__main__":
main()
</syntaxhighlight>
Explicatie[edit | edit source]
∑5i=1i*3=1**3+2**3+3**3+4**3+5**3=225