Cod sursa(job #347084)

Utilizator CezarMocanCezar Mocan CezarMocan Data 10 septembrie 2009 21:25:49
Problema Calcul Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.09 kb
#include <cstdio>
#include <cstring>

using namespace std;

char s[100100], b[100100];
char t[400100];
int c, a, i, j, n, mod, d, nr, ind;
int mat[2][2], t1[2][2], t2[2][2], sol[2][2];

inline void scade() {
	int i = 1;
	while (t[i] == 0) {
		t[i] = 1;
		i++;
	}
	t[i]--;
	for (; d > 1 && !t[d]; d--);	
}

inline void mult(int a[][2], int b[][2], int c[][2]) {
	int i, j, k;
	for (i = 0; i < 2; i++)
		for (j = 0; j < 2; j++)
			for (k = 0; k < 2; k++)
				c[i][j] = (c[i][j] + 1LL * a[i][k] * b[k][j]) % mod;
}


void lg_pow(int m[][2]) {
	int p[2][2];
	if (ind == d) {
		memcpy(m, mat, sizeof(mat));
		return;
	}
	
	if (t[ind] % 2 == 0) {
		memset(p, 0, sizeof(p));
		ind++;
		lg_pow(p);
		mult(p, p, m);
	}
	else {
		t[ind] = 0;
		memset(p, 0, sizeof(p));
		lg_pow(p);
		mult(p, mat, m);
	}
}

inline void swap(char &a, char &b) {
	char aux;
	aux = a; a = b; b = aux;
}

inline int max(int a, int b) {
	if (a > b)
		return a;
	return b;
}

int main() {
	freopen("calcul.in", "r", stdin);
	freopen("calcul.out", "w", stdout);
	
	scanf(" %s ", s);
	scanf(" %s ", b);
	scanf("%d", &c);
	
	mod = 1; 
	for (i = 1; i <= c; i++)
		mod *= 10;
	
	for (n = 0; s[n] != 0; n++);
	n--;
	
	for (i = max(n - c + 1, 0); i <= n; i++)
		a = a * 10 + (s[i] - 48);
	
	if (a == 0) {
		for (i = 1; i <= c; i++)
			printf("0");
		return 0;
	}
	
	for (n = 0; b[n] != 0; n++);
	n--;
	
	for (i = 0; i <= n / 2; i++)
		swap(b[i], b[n - i]);
	
	for (i = 0; i <= n; i++) {
		if (b[i] >= 'A')
			nr = b[i] - 'A' + 10;
		else
			nr = b[i] - 48;
		
		while (nr > 0) {
			d++;
			t[d] = nr % 2;
			nr /= 2;
		}
		
		if (i < n)
			while (d != 4 * i + 4) {
				d++;
				t[d] = 0;
			}
	}
	
	scade();
	
	mat[0][0] = a; mat[0][1] = 1; mat[1][0] = 0; mat[1][1] = 1;
	if (t[d] != 0) {
		ind = 1;
		lg_pow(t1);
		t2[0][0] = a * a; t2[0][1] = a; t2[1][0]  = a; t2[1][1] = 0;
		mult(t2, t1, sol);
	}
	else
		sol[0][1] = a;
	
	int aux = sol[0][1];
	while (aux * 10 < mod) {
		aux *= 10;
		printf("0");
	}
	
	printf("%d\n", sol[0][1]);
	
	return 0;
}