Antipalindromik sətrlər#9616

Antipalindromik sətrlər (Həll təhlili)

Əgər bir sıra uzunluğu və ya olan palindrome alt stringlər içərmirsə, onda o, ümumiyyətlə birdən uzun palindrome alt stringlər içərmir.

Əgər n = 1 olarsa, uzunluğu olan bir sıra hərfdən istənilən birini təşkil edə bilər. Bu halda uyğun olan sıranın sayı olur.

Əgər m = 1 və n > 1 olarsa, cavab bərabərdir, çünki formasında yalnız bir mümkün sıra mövcuddur və o, palindrome -nı içərir.

Əgər n = 2 olarsa, sıranın birinci pozisiyasında istənilən hərfi yerləşə bilər və ikinci pozisiyada — qalan m - 1 hərfdən istənilən biri. Birinci və ikinci pozisiyalardakı hərflər eyni olmamalıdır, əks halda onlar uzunluğu olan palindrome yaradırlar. Beləliklə, aranan sıranın sayı bərabərdir

(m \cdot (m - 1))~mod~10^9 + 7

Güman edək ki, sıranın uzunluğu -dən böyükdür. Birinci pozisiyada istənilən hərfi, ikinci pozisiyada istənilən m - 1 hərfi ola bilər. Üçüncü pozisiyadakı hərf palindrome uzunluğu olmasın deyə ikinci pozisiyadakı hərfdən fərqlənməlidir, həmçinin birinci pozisiyadakı hərfdən fərqlənməlidir ki, ilk üç simvol uzunluğu olan palindrome yaratmasın. Beləliklə, üçüncü pozisiyada istənilən m - 2 hərfi ola bilər.

Bu məntiqi izləərək anlayırıq ki, -ci pozisiyadakı hərf i - 1 və i - 2 pozisiyalarındakı hərflərdən fərqlənməlidir. Beləliklə, üçüncü pozisiyadan başlayaraq hər bir pozisiya üçün hərfin seçilməsi üçün tam olaraq m - 2 icazə verilmiş seçim variantı var.

Beləliklə, aranan sıranın sayı bərabərdir

(m \cdot (m - 1) \cdot (m - 2)^{n - 2})~mod~10^9 + 7

Alqoritmin tətbiqi

Bütün hesablamaların yerinə yetirildiyi modulu elan edirik.

#define MOD 1000000007

powmod funksiyası x^n~mod~m dəyərini hesablayır.

long long powmod(long long x, long long n, long long m)
{
  if (n == 0) return 1;
  if (n % 2 == 0) return powmod((x * x) % m, n / 2, m);
  return (x * powmod(x, n - 1, m)) % m;
}

Proqramın əsas hissəsi. Giriş məlumatlarını oxuyuruq.

scanf("%d", &tests);
while (tests--)
{
  scanf("%lld %lld", &n, &m);

və dəyərlərinə əsasən cavabı hesablayırıq.

  if (n == 1) res = m; else
  if (m == 1) res = 0; else // n > 1, m = 1:  aa....a
  if (n == 2) res = (m * (m - 1)) % MOD; else
  res = ((m * (m - 1)) % MOD * powmod(m - 2, n - 2, MOD)) % MOD;

Cavabı çıxarırıq.

  printf("%lld\n", res);
}