Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //TIOJ 2005
- #include <bits/stdc++.h>
- using namespace std;
- #define int long long
- int cur[3][3];
- int uni[3][3] = {{1,0,0},{1,1,0},{0,1,1}};
- int m;
- void self(){
- int des[3][3] = {{0}};
- for(int i = 0; i < 3; ++i){
- for(int j = 0; j < 3; ++j){
- for(int k = 0; k < 3; ++k){
- des[i][j] += cur[i][k] * cur[k][j];
- des[i][j] %= m;
- }
- }
- }
- memcpy(cur, des, sizeof(cur));
- }
- void mode(){
- int des[3][3] = {{0}};
- for(int i = 0; i < 3; ++i){
- for(int j = 0; j < 3; ++j){
- for(int k = 0; k < 3; ++k){
- des[i][j] += cur[i][k] * uni[k][j];
- des[i][j] %= m;
- }
- }
- }
- memcpy(cur, des, sizeof(cur));
- }
- void matmi(int n){
- if(n == 1){
- memcpy(cur, uni, sizeof(cur));
- }else if(n & 1){
- matmi(n / 2);
- self();
- mode();
- }else{
- matmi(n / 2);
- self();
- }
- }
- int32_t main(){
- int n;
- while(cin >> n >> m){
- uni[0][0] = 1;
- int ans = 0;
- int dig = 0;
- while(uni[0][0] <= n){
- ++dig;
- uni[0][0] *= 10;
- int down = uni[0][0] / 10 - 1;
- int up = min(uni[0][0] - 1, n);
- matmi(up-down);
- /*for(int i = 0; i < 3; ++i){
- for(int j = 0; j < 3; ++j){
- cout << cur[i][j] << ' ';
- }
- cout << endl;
- }*/
- ans = cur[0][0] * (ans) % m + cur[1][0] * (down+1) % m + cur[2][0];
- ans %= m;
- }
- cout << ans << '\n';
- }
- return 0;
- }
- /*
- F(n) = F(n-1) * 10 + n
- F(0) = 0;
- F(1) = 1;
- 10 0 0
- 1 1 0
- 0 1 1
- F(n-1) n 1 = F(n) n+1 1
- */
Advertisement
Add Comment
Please, Sign In to add comment