Skip to content

Commit 67b7d58

Browse files
committed
compute the function value
1 parent ac2649c commit 67b7d58

1 file changed

Lines changed: 131 additions & 0 deletions

File tree

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import sys
2+
3+
T, mod = map(int, sys.stdin.readline().split())
4+
5+
# I multiply mod by 4 because I cannot use modular inverse
6+
mod = mod * 4
7+
8+
9+
def func(n):
10+
11+
# Compute the value of f(n)
12+
# The general formula is:
13+
# f(n) = 2 * ( sum( (-1)^i*(-1)^(n//2)* 3^i), i = 1 to n//2 - 1) + 1
14+
#
15+
# For example if we have to compute f(8) then we have:
16+
# f(8) = 2*3^3 - 2*3^2 + 2*3 + 1
17+
18+
# All values have multiplied by 4
19+
if n <= 2:
20+
return 4
21+
22+
if n % 2 == 1:
23+
return ( 4 * pow(3, n//2, mod) ) % mod
24+
else:
25+
if (n // 2 ) % 2 == 0:
26+
return ( 6 * ( pow(3, n//2 - 1, mod) + 1 ) + 4 ) % mod
27+
else:
28+
return ( 6 * ( pow(3, n//2 - 1, mod) - 1 ) + 4 ) % mod
29+
30+
31+
for _ in range(T):
32+
L, R = map(int, sys.stdin.readline().split())
33+
34+
# Compute the sum of odd elements
35+
# (e.g for (L, R) = (5, 20) we have f(5) + f(7) + f(9) + ... + f(19)
36+
#
37+
# If n is odd we have: f(n) = 3^(n//2)
38+
# For the above example sum = 3^2 + 3^3 + ... + 3^9
39+
40+
# Find first power of 3
41+
f_elem = L // 2
42+
43+
# Find last power of 3
44+
l_elem = (R - 1) // 2
45+
46+
# Finally we have total = 3^f_elem + 3^(f_elem+1) + ... + 3^(l_elem)
47+
#
48+
# The general formula is sum = 1/2 * ( 3^(l_elem+1) - 3^(f_elem) ) and
49+
# because we multiply all by 4 we have
50+
# sum = 2 * ( 3^(l_elem+1) - 3^(f_elem) )
51+
total = ( ( pow(3, l_elem+1, mod) - pow(3, f_elem, mod) ) * 2 ) % mod
52+
53+
# Compute the sum of even elements
54+
# (e.g for (L, R) = (5, 20) we have f(6) + f(8) + f(10) + ... + f(20)
55+
56+
# Find first element that is an even number
57+
if L % 2 == 0:
58+
f_even = L
59+
else:
60+
f_even = L + 1
61+
62+
# Find last element that is an even number
63+
if R % 2 == 0:
64+
l_even = R
65+
else:
66+
l_even = R - 1
67+
68+
# Count the number of even elements
69+
evens = (R - f_even) // 2 + 1
70+
71+
# Let's take an example:
72+
# f(8) = 2*f(7) - f(6) + 2 ==> f(6) + f(8) = 2*f(7) + 2
73+
74+
# So in our example the sum of even elements is:
75+
# f(6) + f(8) + f(10) + f(12) + f(14) + f(16) + f(18) + f(20) =
76+
# = 2*f(7) + 2 + 2*f(11) + 2 + 2*f(15) + 2 + 2*f(19) + 2
77+
78+
if evens % 2 == 0:
79+
80+
# if the number of even elements is even we have the formula
81+
# a) all powers of 3 are odd numbers. total = 2 * sum( 3^(2*i + 1) ) + 2 * evens and finally
82+
# b) all powers of 3 are even numbers. total = 2 * sum( 3^(2*i) ) + evens and finally
83+
#
84+
# and the general formulas for sums are:
85+
# a) sum = 3/4 * ( 9^(n+1) - 9^k)
86+
# b) sum = 1/4 * ( 9^(n+1) - 9^k)
87+
# where n, k is first and last i in the above formulas
88+
89+
f_even += 2
90+
91+
# Find first and last power of i
92+
k = (f_even // 2 - 1) // 2
93+
n = (l_even // 2 - 1) // 2
94+
95+
# Compute the sum of even elements
96+
# All formulas have multiplied by 4
97+
if f_even % 4 != 0:
98+
total = ( total + ( ( pow(9, n+1, mod) - pow(9, k, mod)) ) % mod ) % mod
99+
else:
100+
total = ( total + ( 3 * ( pow(9, n+1, mod) - pow(9, k, mod)) ) % mod ) % mod
101+
102+
# Add the evens multiplied by 4
103+
total = ( total + 4 * evens ) % mod
104+
105+
else:
106+
107+
# In the case that we have odd number of even elements we have to compute the value
108+
# of the first even element and after that we follow the above procedure
109+
110+
# Compute the value of first even element
111+
total = ( total + func(f_even) ) % mod
112+
113+
# Compute the value of all the other even elemnts
114+
# with the above procedure
115+
f_even += 4
116+
117+
k = ( f_even // 2 - 1 ) // 2
118+
n = ( l_even // 2 - 1 ) // 2
119+
120+
if f_even % 4 != 0:
121+
total = ( total + ( ( pow(9, n+1, mod) - pow(9, k, mod)) ) % mod ) % mod
122+
else:
123+
total = ( total + ( 3 * ( pow(9, n+1, mod) - pow(9, k, mod)) ) % mod ) % mod
124+
125+
# We have to remove first even element
126+
total = ( total + 4 * ( evens // 2 ) * 2 ) % mod
127+
128+
129+
# we finally divide by 4
130+
print(total // 4)
131+

0 commit comments

Comments
 (0)