fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. int phi(int n) {
  5. int res = n;
  6. for (int i = 2; i*i <= n; ++i)
  7. if (n % i == 0) {
  8. while (n % i == 0)
  9. n /= i;
  10. res -= res / i;
  11. }
  12. if (n > 1)
  13. res -= res / n;
  14. return res;
  15. }
  16.  
  17. vector <int> factorize(int x) {
  18. vector <int> res;
  19. for (int i = 2; i*i <= x; ++i) {
  20. if (x%i == 0) {
  21. res.push_back(i);
  22. }
  23. while (x%i == 0) {
  24. x /= i;
  25. }
  26. }
  27. if (x > 1) res.push_back(x);
  28. return res;
  29. }
  30.  
  31. #define fmod i_love_pelmeny
  32.  
  33. int mod;
  34. vector <int> fmod;
  35. const int N = (int)2e5+10;
  36. vector <pair <int, int> > f[N];
  37. vector <int> pw[25];
  38. //vector <int> realpw[25];
  39. int goodpart[N];
  40. int inv[N];
  41. int n, a[N];
  42. int id[N];
  43.  
  44. int binpow(int a, int b) {
  45. int res = 1;
  46. while (b > 0) {
  47. if (b&1) res = 1ll*res*a%mod;
  48. b >>= 1;
  49. a = 1ll*a*a%mod;
  50. }
  51. return res;
  52. }
  53.  
  54. struct node {
  55. vector <int> degrees;
  56. int tl, tr;
  57. int sum, here;
  58. bool flag = false;
  59. node *le, *ri;
  60.  
  61. int calc_real_sum() {
  62. // if (!flag) return sum;
  63. int res = here;
  64. for (int i = 0; i < degrees.size(); ++i) {
  65. res = 1ll*res*pw[i][degrees[i]]%mod;
  66. }
  67. return res;
  68. }
  69. void push_down() {
  70. if (!flag) return;
  71. int i = 0;
  72. for (auto & x : degrees) {
  73. le->degrees[i] += x;
  74. ri->degrees[i] += x;
  75.  
  76. le->sum = 1ll*le->sum*pw[i][x]%mod;
  77. ri->sum = 1ll*ri->sum*pw[i][x]%mod;
  78.  
  79. x = 0;
  80. ++i;
  81. }
  82. le->here = 1ll*le->here*here%mod;
  83. le->sum = 1ll*le->sum*here%mod;
  84. ri->here = 1ll*ri->here*here%mod;
  85. ri->sum = 1ll*ri->sum*here%mod;
  86. here = 1;
  87. flag = false;
  88. le->flag = ri->flag = true;
  89. }
  90. void combine() {
  91. sum = (le->sum+ri->sum)%mod;
  92. }
  93.  
  94. void multiply(int l, int r, int x) {
  95. if (r < tl || tr < l) return;
  96. if (l <= tl && tr <= r) {
  97. flag = true;
  98. for (auto p : f[x]) {
  99. degrees[id[p.first]-1] += p.second;
  100. }
  101. here = 1ll*here*goodpart[x]%mod;
  102. sum = 1ll*sum*x%mod;
  103. return;
  104. }
  105. push_down();
  106. le->multiply(l, r, x);
  107. ri->multiply(l, r, x);
  108. combine();
  109. }
  110. void divide(int pos, int x) {
  111. if (tl == tr) {
  112. for (auto p : f[x]) {
  113. degrees[id[p.first]-1] -= p.second;
  114. }
  115. here = 1ll*here*inv[goodpart[x]]%mod;
  116. sum = calc_real_sum();
  117. return;
  118. }
  119. push_down();
  120. if (pos <= (tl+tr)/2) {
  121. le->divide(pos, x);
  122. } else {
  123. ri->divide(pos, x);
  124. }
  125. combine();
  126. }
  127. int get(int l, int r) {
  128. if (r < tl || tr < l) {
  129. return 0;
  130. }
  131. if (l <= tl && tr <= r) {
  132. return sum;
  133. }
  134. push_down();
  135. return (le->get(l, r)+ri->get(l, r))%mod;
  136. }
  137. node(int l, int r, int dsize) {
  138. tl = l;
  139. tr = r;
  140. sum = 1;
  141. here = 1;
  142. degrees.resize(dsize);
  143. if (l == r) {
  144. multiply(l, r, a[l]);
  145. return;
  146. }
  147. le = new node(l, (l+r)/2, dsize);
  148. ri = new node((l+r)/2+1, r, dsize);
  149. combine();
  150. }
  151. };
  152.  
  153. struct query {
  154. int x, l, r, t;
  155. query() {}
  156. };
  157.  
  158. node *t;
  159. vector <query> q;
  160.  
  161. void precalc_base() {
  162. fmod = factorize(mod);
  163. if (fmod.back() >= N) fmod.pop_back();
  164. vector <int> deg(N);
  165. for (int i = 0; i < fmod.size(); ++i) {
  166. id[fmod[i]] = i+1;
  167. for (int j = fmod[i]; j < N; j += fmod[i]) {
  168. if ((j/fmod[i])%fmod[i]) {
  169. deg[j] = 1;
  170. } else {
  171. deg[j] = deg[j/fmod[i]]+1;
  172. }
  173. f[j].emplace_back(fmod[i], deg[j]);
  174. }
  175. }
  176.  
  177. for (int i = 1; i < N; ++i) {
  178. goodpart[i] = i;
  179. goodpart[i] = goodpart[i/__gcd(i, mod)];
  180. }
  181. }
  182. void precalc_inverse() {
  183. vector <int> mn(N);
  184. for (int i = 2; i < N; ++i) {
  185. if (mn[i]) continue;
  186. for (int j = i+i; j < N; j += i) {
  187. if (!mn[j]) mn[j] = i;
  188. }
  189. }
  190.  
  191. int mod_phi = phi(mod);
  192. inv[1] = 1;
  193. for (int i = 2; i < N; ++i) {
  194. if (!mn[i]) inv[i] = binpow(i, mod_phi-1);
  195. else inv[i] = 1ll*inv[i/mn[i]]*inv[mn[i]]%mod;
  196. }
  197. }
  198. void precalc_powers() {
  199. vector <int> max_entry(fmod.size());
  200. for (int i = 1; i <= n; ++i) {
  201. for (auto p : f[a[i]]) {
  202. max_entry[id[p.first]-1] += p.second;
  203. }
  204. }
  205.  
  206. for (const auto& w : q) {
  207. if (w.t != 1) continue;
  208. for (auto p : f[w.x]) {
  209. max_entry[id[p.first]-1] += p.second;
  210. }
  211. }
  212.  
  213. for (int i = 0; i < fmod.size(); ++i) {
  214. pw[i].resize(max_entry[i]+1);
  215. pw[i][0] = 1;
  216. for (int j = 1; j < pw[i].size(); ++j) {
  217. pw[i][j] = 1ll*pw[i][j-1]*fmod[i]%mod;
  218. }
  219. }
  220.  
  221. }
  222. void precalc() {
  223. precalc_base();
  224. precalc_inverse();
  225. precalc_powers();
  226. t = new node(1, n, fmod.size());
  227. cerr << 1.0*clock()/CLOCKS_PER_SEC << endl;
  228. }
  229.  
  230. int main() {
  231. // ios_base::sync_with_stdio(0);
  232. #ifdef LOCAL
  233. freopen("input.txt", "r", stdin);
  234. freopen("output.txt", "w", stdout);
  235. #endif // LOCAL
  236. scanf("%d%d", &n, &mod);
  237. for (int i = 1; i <= n; ++i) {
  238. scanf("%d", &a[i]);
  239. }
  240. int m; scanf("%d", &m);
  241. q.resize(m);
  242. for (int i = 0; i < m; ++i) {
  243. scanf("%d", &q[i].t);
  244. scanf("%d", &q[i].l);
  245. if (q[i].t != 2)
  246. scanf("%d", &q[i].r);
  247. if (q[i].t != 3)
  248. scanf("%d", &q[i].x);
  249. }
  250. precalc();
  251. for (const auto& p : q) {
  252. if (p.t == 1) {
  253. t->multiply(p.l, p.r, p.x);
  254. }
  255. if (p.t == 2) {
  256. t->divide(p.l, p.x);
  257. }
  258. if (p.t == 3) {
  259. printf("%d\n", t->get(p.l, p.r));
  260. }
  261. }
  262.  
  263. }
  264.  
Runtime error #stdin #stdout 0s 23088KB
stdin
Standard input is empty
stdout
Standard output is empty