Submit solution
Points:
100.00 (partial)
Time limit:
1.0s
Memory limit:
256M
Input:
stdin
Output:
stdout
Author:
Suggester:
Problem type
Một số tự nhiên được gọi là số STN nếu thỏa mãn hai điều kiện:
- Số chính phương là số có thể viết dưới dạng ~n^2~ (ví dụ: 1, 4, 9, 16, 25, 36, …).;
- Số tam giác là số có thể viết dưới dạng: ~T_n = \frac{n(n+1)}{2}~ .
Sắp xếp tăng dần các số STN ta được dãy vô hạn số STN, các số đầu tiên của dãy là: 1, 36, 1225, 41616, 1413721, 48024900,…
Yêu cầu: Cho hai số nguyên dương 𝑘 và 𝑀, gọi 𝑁 là số STN thứ 𝑘 trên dãy (các số trên dãy được đánh thứ tự bắt đầu từ 1), tính phần dư khi chia 𝑁 cho 𝑀.
Dữ liệu vào: là dạng chuẩn có định dạng như sau:
- Dòng đầu ghi số nguyên dương 𝑇 (𝑇 ≤ 100) là số bộ dữ liệu;
- 𝑇 dòng sau, mỗi dòng tương ứng với một bộ dữ liệu chứa hai số nguyên dương 𝑘, 𝑀.
Dữ liệu ra: gồm 𝑇 dòng tương ứng với 𝑇 bộ dữ liệu trong dữ liệu vào, mỗi dòng ghi một số là phần dư khi chia 𝑁 cho 𝑀.
Ví dụ
Input:
2
2 10
5 10
Output:
6
1
Ràng buộc:
- Có 20% số test có ~𝑘 ≤ 5; 𝑀 ≤ 10^9~;
- Có 20% số test khác có ~𝑘 ≤ 10; 𝑀 ≤ 10^9;
- Có 20% số test khác có ~𝑘 ≤ 20; 𝑀 ≤ 10^9;
- Có 20% số test khác có ~𝑘 ≤ 10^9; 𝑀 ≤ 10^9~;
- Có 20% số test còn lại có ~𝑘 ≤ 10^18; 𝑀 ≤ 10^18~.
Comments
include <bits/stdc++.h>
using namespace std; using ll = long long; using u128 = _uint128t; // để in ra dễ hơn khi cần kiểm tra
// Nhân nhanh kiểu Ấn Độ: (a * b) % mod, tránh tràn 64-bit ll mulmod(ll a, ll b, ll mod) { _int128 res = 0; __int128 x = a % mod, y = b; while (y > 0) { if (y & 1) res = (res + x) % mod; x = (x + x) % mod; y >>= 1; } return (ll)res; }
// Nhân 2 ma trận 2x2 mod M void matmul(ll A[2][2], ll B[2][2], ll M, ll C[2][2]) { ll res[2][2]; res[0][0] = ( (mulmod(A[0][0], B[0][0], M) + mulmod(A[0][1], B[1][0], M)) % M ); res[0][1] = ( (mulmod(A[0][0], B[0][1], M) + mulmod(A[0][1], B[1][1], M)) % M ); res[1][0] = ( (mulmod(A[1][0], B[0][0], M) + mulmod(A[1][1], B[1][0], M)) % M ); res[1][1] = ( (mulmod(A[1][0], B[0][1], M) + mul_mod(A[1][1], B[1][1], M)) % M ); C[0][0] = res[0][0]; C[0][1] = res[0][1]; C[1][0] = res[1][0]; C[1][1] = res[1][1]; }
// Lũy thừa ma trận nhanh void mat_pow(ll base[2][2], long long exp, ll M, ll res[2][2]) { // ma trận đơn vị res[0][0] = 1 % M; res[0][1] = 0; res[1][0] = 0; res[1][1] = 1 % M;
}
// Tính yk theo công thức truy hồi y{n+1} = 6 yn - y{n-1} // y1 = 1, y2 = 6 ll yk_mod(long long k, ll M) { if (M == 1) return 0; if (k == 1) return 1 % M; if (k == 2) return 6 % M;
}
// Trả về (yk^2) % M ll squaretriangularmod(long long k, ll M) { ll y = ykmod(k, M); return mul_mod(y, y, M); }
int main() { ios::syncwithstdio(false); cin.tie(nullptr); freopen("input.05","r",stdin);
freopen("output.05","w",stdout); int T; cin >> T; while (T--) { long long k, M; cin >> k >> M; cout << squaretriangularmod(k, M) << "\n"; } return 0; }