Tutaq ki, d_1, d_2, ..., d_n — giriş ədədləridir. Bu ədədlərin hamısının qismən cəmlərini nəzərdən keçirək
Qismən cəmlərin sayı məhz olduğuna görə, bütün s_i~mod~n qiymətləri arasında ya iki bərabər, ya da ən az biri sıfıra bərabər olan bir dəyər mütləq tapılacaq.
Əgər bəzi indekslər üçün a - 1 < b şərti ödənirsə
onda d_a + ... + d_b cəmi -ə bölünür.
Nəticədə, d_a, d_{a + 1}, ..., d_b ədədlər ardıcıllığı axtarılan ardıcıllıqdır.
Əgər elədə bir mövcuddursa ki, s_i~mod~n = 0, onda axtarılan ardıcıllıq d_1, d_2, ..., d_i olacaqdır.
Nümunə
Gətirilmiş nümunəni nəzərdən keçirək. Bütün qismən cəmləri hesablayacağıq:
Axtarılan dəstlərdən bir neçə var. Məsələn:
çünki s_1 = s_3, onda d_2 + d_3 = 5 -ə bölünür.
çünki s_1 = s_5, onda d_2 + d_3 + d_4 + d_5 = 10 -ə bölünür.
çünki s_3 = s_5, onda d_4 + d_5 = 5 -ə bölünür.
çünki s_4 = 0, onda d_1 + d_2 + d_3 + d_4 = 10 -ə bölünür.
Alqoritmin həyata keçirilməsi
Giriş ədədlərini massivində saxlayacağıq. Qismən cəmləri fiksasiya etmək üçün massivindən istifadə edəcəyik: əgər s = d_1 + ... + d_i, onda r[s] = i əmrini verəcəyik.
#define MAX 10100
int d[MAX], r[MAX];Cəmləri -ə bölünən axtarılan ədədlər dəsti d_a, d_{a+1}, ..., d_b olacaq. Onların sayını b - a + 1 çıxış edəcəyik, sonra isə ədədlərin özlərini hər sətirdə birini olmaqla verəcəyik.
void print(int a, int b)
{
printf("%d\n",b - a + 1);
for(int i = a; i <= b; i++)
printf("%d\n",d[i]);
}Proqramın əsas hissəsi. massivini ilə başla və ilk ədədlərinin cəmi -ə bölünəndə r[0] = 0 ayarla.
memset(r,-1,sizeof(r)); r[0] = 0;Ədədlərin sayını oxuyuruq.
scanf("%d",&n);Qismən cəmləri -ə modal olaraq dəyişənində hesablayırıq.
sum = 0;
for (i = 1; i <= n; i++)
{
scanf("%d", &d[i]);
sum = (sum + d[i]) % n;Əgər qismən cəm təkrarlanarsa, axtarılan ədədlər dəstini çıxış edirik:
if (r[sum] != -1)
{
print(r[sum] + 1, i);
break;
}ilk indeksini saxlayır, burada d_1 + ... + d_i qismən cəmi -ə bölündükdə qalan olur.
else r[sum] = i;
}