Problem:
Score : 800 points

Problem Statement

For a positive integer n, we denote the integer obtained by reversing the decimal notation of n (without leading zeroes) by rev(n). For example, rev(123) = 321 and rev(4000) = 4.

You are given a positive integer D. How many positive integers N satisfy rev(N) = N + D?

Constraints

D is an integer.

1 ≤ D < 10^9

Input

Input is given from Standard Input in the following format:

D

Output

Print the number of the positive integers N such that rev(N) = N + D.

Sample Input 1

63

Sample Output 1

2

There are two positive integers N such that rev(N) = N + 63: N = 18 and 29.

Sample Input 2

75

Sample Output 2

0

There are no positive integers N such that rev(N) = N + 75.

Sample Input 3

864197532

Sample Output 3

1920

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
#define all(V) V.begin(),V.end()
#define FINISH cout<<"NO"<<endl;return 0
using ll = long long;
const ll MOD = 1000000007;

map<ll, ll> sa, st;
bool mp;
vector<pair<ll, ll>> V[2], Vsb;
ll R[3400010];

void zrk(ll d, ll p, ll n, ll k, ll low, ll up) {
	if (d == 0) {
		V[mp].push_back({ n,p });
		return;
	}
	if (k == 0) {
		V[mp].push_back({ n, p * 10 });
		return;
	}
	//cout << d << " " << p << " " << n << " " << k << " " << low << " " << up << endl;
	for (auto s : sa)
		zrk(d - 1, p * s.second, n + k * s.first, low / 10 - up * 10, low / 10, up * 10);
}

void zrkf(ll d, ll p, ll n, ll k, ll low, ll up) {
	if (d == 0) {
		V[mp].push_back({ n,p });
		return;
	}
	//cout << d << "f" << p << "f" << n << " " << k << " " << low << " " << up << endl;
	for (auto s : st)
		zrk(d - 1, p * s.second, n + k * s.first, low / 10 - up * 10, low / 10, up * 10);
}

int main() {
	for (int i = 0;i < 10;i++) {
		for (int j = 0;j < 10;j++) {
			if (sa.count(i - j))sa[i - j]++;
			else sa.insert({ i - j,1 });
			if (j > 0 && i >= j) {
				if (st.count(i - j))st[i - j]++;
				else st.insert({ i - j,1 });
			}
		}
	}

	int D;
	cin >> D;
	
	ll r9, r10, r1, vs0, vs1, s0, s1;

	map<ll, ll> M, NM;

	ll ans = 0;
	for (int i = 2;i < 19;i++) {
		r9 = 9, r10 = 10;
		for (int j = 2;j < i;j++) {
			r9 *= 10;
			r9 += 9;
			r10 *= 10;
		}

		ll ser = (i + 1) / 2;
		r1 = 1;
		mp = 0;
		zrkf(ser - ser / 2, 1, 0, r9, r10, 1);

		//cout << ser - ser / 2 << " " << r10 << " " << r1 << endl;
		for (int j = 0;j < ser - ser / 2;j++)r10 /= 10, r1 *= 10;
		//cout <<  ser / 2 << " " << r10 << " " << r1 << endl;

		mp = 1;
		zrk(ser / 2, 1, 0, r10 - r1, r10, r1);

		sort(all(V[0]));
		sort(all(V[1]));
		
		vs0 = V[0].size();
		vs1 = V[1].size();
		R[0] = 0;
		for (int j = 1;j <= vs1;j++)
			R[j] = R[j - 1] + V[1][j - 1].second;

		pair<ll, ll> sr;
		for (int j = 0;j < vs0;j++) {
			sr = { D - V[0][j].first,LLONG_MIN };
			auto it = lower_bound(all(V[1]), sr);

			sr.first++;
			auto it2 = lower_bound(all(V[1]), sr);

			s0 = it - V[1].begin();
			s1 = it2 - V[1].begin();
			ans += (R[s1] - R[s0]) * V[0][j].second;
		}
		for (int j = 0;j <= vs1;j++) {
			R[j] = 0;
		}
		V[0] = Vsb;
		V[1] = Vsb;
	}
	cout << ans << endl;
}