#include #include #include #include #include #include #include #include #include #include using namespace std; #define MEM(a,b) memset(a,(b),sizeof(a)) #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) #define MP make_pair #define pb push_back #define maxo 1000 #define maxb 16 #define maxt 5 typedef long long LL; typedef pair pl; typedef pair pli; typedef pair pi; typedef vector vi; unsigned long long pw[105][100]; inline LL getmask(LL x) { return ((LL)1< > next; }; class PalindromeBases { public: int b1,b2,maxPow[100]; vector A,B,ans; vector TA,TB; void init() { for(int i=2,j;i<=maxb;i++) { pw[i][0] = 1; for(j=1;pw[i][j-1] solve(int _b1,int _b2) { ans.clear(); b1=_b1;b2=_b2; for(int l1=3;;l1++) { int d=(l1+3)/4,e=(l1-d*2+1)/2; //d = length of 1st and 4th part, e=length of 2nd and 3rd part A.clear(); gen(0,d,l1-1,0,A,0); // generate b1 palindromes considering 1st and 4th part B.clear(); gen(0,e,l1-1-d,d,B,0); // generate b1 palindromes considering 2nd and 3rd part if(A.empty() || B.empty()) break; sort(A.begin(),A.end()); sort(B.begin(),B.end()); // get possible length ranges when b1 palindrome has length=l1 LL minu=A[0]+B[0]; LL maxu=min(maxv,A[A.size()-1]+B[B.size()-1]); int l2min = getDigits(minu,b2); int l2max = getDigits(maxu,b2); for(int l2=l2min;l2<=l2max;l2++) { // compute the trie with prefix,suffix info from the 2sets of palindromes calcPart(l2,A,TA); calcPart(l2,B,TB); solve(0,0,0,0,0,l2,0,0); } if((int)ans.size()>=maxo) break; // already got 1000 first palindromes } for(int i=1;i &A,vector &nodes) { nodes.clear(); nodes.pb(node()); for(int i=0;ipw[b2][l]-1) break; for(int j=0;j<=l/2;j++) { if(j==l/2 && !(l&1)) continue; int a=VAL(x,b2,l-1-j),b=VAL(x,b2,j); // get the digits in b2 y += pw[b2][l-1-j]*a; // add from left part if( j != l-1-j) y += pw[b2][j]*b; // add from right part int dig=a*b2+b,next=-1; for(int k=0;k &A,LL x) { if(pos==pl) { if(x) A.push_back(x); if(rightOffset==0 && isPal(x,b2,getDigits(x,b2))) ans.pb(x); return; } int l=leftOffset-pos,r=rightOffset+pos; for(int i=0;imaxPow[b1] || pw[b1][l]>maxv/i) ) return; LL nx= x + pw[b1][l]*i; if(l!=r) nx += pw[b1][r]*i; if(nx>maxv) break; gen(pos+1,pl,leftOffset,rightOffset,A,nx); } } }; PalindromeBases pal; int main() { int T,b1,b2; pal.init(); cin>>T; assert(T>=1 && T<=maxt); while(T--) { cin>>b1>>b2; assert(2<=b1 && b1 res = pal.solve(b1,b2); for(int i=0;i