1. #include <cstdio>
    2. #include <algorithm>
    3. #include <cstring>
    4. #include <cmath>
    5. #include <vector>
    6. #include <cstdlib>
    7. #include <iostream>
    8. #include <queue>
    9. using namespace std;
    10. #define ll long long
    11. #define For(i, l, r) for (int i = (int)(l); i <= (int)(r); ++i)
    12. #define in(x) x = gi()
    13. inline int gi()
    14. {
    15. char tmp = getchar();
    16. int ans = 0;
    17. while (!isdigit(tmp))
    18. tmp = getchar();
    19. while (isdigit(tmp))
    20. ans = ans * 10 + tmp - '0', tmp = getchar();
    21. return ans;
    22. }
    23. const int N = 1e5 + 10;
    24. #define LOG 58
    25. int n, m, p, c;
    26. int cntp;
    27. struct Seg
    28. {
    29. int min, sum;
    30. } T[N << 2];
    31. #define ls (pos << 1)
    32. #define rs (ls | 1)
    33. #define mid ((l + r) >> 1)
    34. #define lson ls, l, mid
    35. #define rson rs, mid + 1, r
    36. inline void Pu(int pos)
    37. {
    38. T[pos].min = min(T[ls].min, T[rs].min);
    39. T[pos].sum = T[ls].sum + T[rs].sum;
    40. while(T[pos].sum >= p) T[pos].sum -= p;
    41. }
    42. int A[LOG][N], Phi[N];
    43. void Update(int pos, int l, int r, int ql, int qr)
    44. {
    45. if (T[pos].min >= cntp)
    46. return;
    47. if (l == r)
    48. {
    49. T[pos].min++;
    50. T[pos].sum = A[T[pos].min][l];
    51. return;
    52. }
    53. if (ql <= mid)
    54. Update(lson, ql, qr);
    55. if (qr > mid)
    56. Update(rson, ql, qr);
    57. Pu(pos);
    58. }
    59. int Query(int pos, int l, int r, int ql, int qr)
    60. {
    61. if (ql <= l && r <= qr)
    62. {
    63. return T[pos].sum;
    64. }
    65. int ans = 0;
    66. if (ql <= mid)
    67. ans += Query(lson, ql, qr);
    68. if (qr > mid)
    69. ans = 1ll * (ans + Query(rson, ql, qr)) % p;
    70. return ans % p;
    71. }
    72. inline int Get(int n)
    73. {
    74. static int t, i, ans;
    75. t = n, ans = n;
    76. for (i = 2; i * i <= n; ++i)
    77. if (t % i == 0)
    78. {
    79. while (!(t % i))
    80. t /= i;
    81. ans = ans / i * (i - 1);
    82. }
    83. if (t > 1)
    84. ans = ans / t * (t - 1);
    85. return ans;
    86. }
    87. int Pow1[1<<16][LOG], Pow2[1<<16][LOG];
    88. inline int Mod(long long x, int p)
    89. {
    90. if (x >= p)
    91. return x % p +p ;
    92. return x;
    93. }
    94. void Pre()
    95. {
    96. For(i, 0, cntp)
    97. {
    98. Pow2[0][i] = Pow1[0][i] = 1;
    99. For(j, 1, (1<<15)-1)
    100. Pow1[j][i] = Mod(1ll * Pow1[j - 1][i] * c, Phi[i]);
    101. Pow2[1][i] = Mod(1ll*Pow1[(1<<15)-1][i]*c,Phi[i]);
    102. For(j, 2, (1<<15)-1)
    103. Pow2[j][i] = Mod(1ll * Pow2[j - 1][i] * Pow2[1][i], Phi[i]);
    104. }
    105. return;
    106. }
    107. int Pow(int a, int b)
    108. {
    109. int j = a & 32767, k = a >> 15;
    110. return Mod(1ll * Pow1[j][b] * Pow2[k][b], Phi[b]);
    111. }
    112. int F(int x, int a, int b)
    113. {
    114. if (!a)
    115. return Mod(x, Phi[b]);
    116. if (b == cntp)
    117. return c ? 1 : 0;
    118. return Pow(F(x, a - 1, b + 1), b);
    119. }
    120. void Build(int pos, int l, int r)
    121. {
    122. if (l == r)
    123. {
    124. T[pos].min = 0;
    125. T[pos].sum = A[0][l];
    126. return;
    127. }
    128. Build(lson), Build(rson);
    129. Pu(pos);
    130. }
    131. signed main()
    132. {
    133. #ifdef NICEGUODONG
    134. freopen("data.in", "r", stdin);
    135. #endif
    136. in(n), in(m), in(p), in(c);
    137. Phi[0]=p;
    138. while(Phi[cntp]>1){
    139. int x=cntp;
    140. Phi[++cntp]=Get(Phi[x]);
    141. }
    142. Phi[++cntp]=1;
    143. Pre();
    144. For(i, 1, n) A[0][i] = gi() ; // diff
    145. For(i, 1, n){
    146. For(j, 1, cntp+1)
    147. A[j][i] = F(A[0][i], j, 0) % p;
    148. A[0][i] %= p;
    149. }
    150. Build(1, 1, n);
    151. // return 0;
    152. For(i, 1, m)
    153. {
    154. int opt, l, r;
    155. in(opt), in(l), in(r);
    156. if (opt == 0)
    157. Update(1, 1, n, l, r);
    158. if (opt == 1)
    159. {
    160. cout << (Query(1, 1, n, l, r)) % p;
    161. putchar('\n');
    162. }
    163. }
    164. return 0;
    165. }