Problem:
Score : 1000 points

Problem Statement

Ringo has a string S.

He can perform the following N kinds of operations any number of times in any order.

Operation i: For each of the characters from the L_i-th through the R_i-th characters in S, replace it with its succeeding letter in the English alphabet. (That is, replace a with b, replace b with c and so on.) For z, we assume that its succeeding letter is a.

Ringo loves palindromes and wants to turn S into a palindrome.
Determine whether this is possible.

Constraints

1 \leq |S| \leq 10^5

S consists of lowercase English letters.

1 \leq N \leq 10^5

1 \leq L_i \leq R_i \leq |S|

Input

Input is given from Standard Input in the following format:

S
N
L_1 R_1
L_2 R_2
:
L_N R_N

Output

Print YES if it is possible to turn S into a palindrome; print NO if it is impossible.

Sample Input 1

bixzja
2
2 3
3 6

Sample Output 1

YES

For example, if we perform Operation 1, 2 and 1 in this order, S changes as bixzja → bjyzja → bjzakb → bkaakb and becomes a palindrome.

Sample Input 2

abc
1
2 2

Sample Output 2

NO

Sample Input 3

cassert
4
1 2
3 4
1 1
2 2

Sample Output 3

YES

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

#include <bits/stdc++.h>

using namespace std;

#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()

template<typename T> inline bool chkmin(T &a, const T &b) { return b < a ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }

typedef long long LL;

const int oo = 0x3f3f3f3f;

const int maxn = 100100;

int N;
int n, qn;
char s[maxn + 5];

int dif[maxn + 5];

int fa[maxn + 5];

int get(int x) { return fa[x] == x ? x : fa[x] = get(fa[x]); }

int sum[maxn + 5];

int where[maxn + 5];

int main()
{
#ifdef matthew99
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	static char tmp[maxn + 5];
	scanf("%s", tmp);
	n = strlen(tmp);
	int cur = 0;
	s[cur++] = '#';
	REP(i, 0, n)
	{
		if ((i << 1) == n) s[cur++] = '#';
		where[i] = cur;
		s[cur++] = tmp[i];
	}
	s[cur++] = '#';
	n = cur;
	int mid = n >> 1;
	N = mid;
	REP(i, 0, N)
	{
		dif[i] = (s[n - (N - i) - 1] - s[n - (N - i)]) - (s[N - i] - s[N - i - 1]);
	}
	REP(i, 0, N) fa[i] = i;
	scanf("%d", &qn);
	REP(i, 0, qn)
	{
		int x, y;
		scanf("%d%d", &x, &y), --x, --y;
		x = where[x];
		y = where[y];
		if (y < mid)
		{
			x = mid - x;
			y = mid - y - 1;
		}
		else if (x > mid)
		{
			x = x - mid - 1;
			y = y - mid;
		}
		else
		{
			x = mid - x;
			y = y - mid;
		}
		fa[get(x)] = get(y);
	}
	REP(i, 0, N) (sum[get(i)] += dif[i]) %= 26;
	REP(i, 0, N) if (fa[i] == i && sum[i])
	{
		puts("NO");
		return 0;
	}
	puts("YES");
	return 0;
}