Niestety, nie byliśmy w stanie w pełni poprawnie wyświetlić tego pliku, ponieważ nie jest zakodowany w UTF-8. Możesz pobrać ten plik i spróbować otworzyć go samodzielnie.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <vector>

typedef long long lLong;
typedef unsigned long uLong;
typedef unsigned long long ulLong;
typedef unsigned int uInt;
typedef unsigned char Byte;

using namespace std;

#define FOR(x, b, e) for(int x=b; x<=(e); ++x)
#define ALL(i) (i).begin(), (i).end()
#define CONTAINS(i,v) (find(ALL(i),v)!=(i).end())
typedef vector<bool> bit_vector;
typedef vector<ulLong> VI;
typedef vector<ulLong> VLL;


#define MAX_N 1001


class PrzypadekTestowy
{
private:	
	int _n;
	lLong _k;

	const char _mapa[4] = { '\0', 'a','b','c' };
	const char _przejscia[4][3] =
	{
		{ 1,2,3 },{ 2,3,0 },{ 1,3,0 },{ 1,2,0 }
	};

	inline void Reset()
	{		
	}

	inline void WczytajWspolczynniki(FILE *input)
	{
		fscanf(input, "%d %lld\n", &_n, &_k);
	}

public:

	inline void WczytajPrzypadekTestowy()
	{
		WczytajPrzypadekTestowy(stdin);
	}
	inline void WczytajPrzypadekTestowy(FILE *input)
	{
		Reset();		
		WczytajWspolczynniki(input);
	}
	inline int WypiszZnak(int poprzedni, int idx)
	{
		poprzedni = _przejscia[poprzedni][idx];
		printf("%c", _mapa[poprzedni]);
		return poprzedni;
	}

	inline void Rozwiaz()
	{
		int poprzedni = 0;
		const int okresMax = 60;

		int minN = min(okresMax, _n);

		//dla n>60 okres przekracza maksymalne k wiec to beda praktycznie same 'ab'
		while (_n > okresMax && _k>1)
		{
			poprzedni = WypiszZnak(poprzedni, 0);
			_n--;
			_k--;
		}

		//obliczenie okresu "startowego" gdy mamy ju� n<=60
		lLong okres = (lLong)pow(2, _n) - 1;

		//je�li k jest poza zakresem zbioru rozwi�za� - to nie ma sensu szuka�
		if (_k > okres*3)
		{
			poprzedni = -2;
			_n = 0;
		}

		while (_n > 0)
		{
			int idx;
			//ustawiamy idx w tym okresie w kt�rym wyst�puje k 
			for (idx = 0; idx < 3; idx++)
			{
				if (_k > okres) _k -= okres;
				else break;
			}			
			poprzedni = WypiszZnak(poprzedni, idx);
			//jesli k osi�gn�o kraniec - to ko�czymy
			if (_k == 1) break;
			_k--;
			_n--;
			//okres bez pierwszego elementu zmniejsza si� o po�ow� - pow(2,_n)-1 te� zadzia�a
			okres = (okres - 1) / 2;			
		}

		if (poprzedni < 0)
		{
			printf("NIE");
		}
		printf("\n");
	}
};

int main(int argc, char **argv)
{	
	FILE *in = stdin;
	if (argc>1)
	{
		in = fopen(argv[1], "rt");
		if (NULL == in)
		{
			in = stdin;
		}
	}
	PrzypadekTestowy p;
	p.WczytajPrzypadekTestowy(in);	
	p.Rozwiaz();	
	return 0;
}