Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.90/21: Рейтинг темы: голосов - 21, средняя оценка - 4.90
C#
57 / 57 / 5
Регистрация: 09.03.2013
Сообщений: 216

Олимпиадная задача - сумма чисел меньших N, которые делятся на A или на B

20.04.2013, 18:22. Показов 4860. Ответов 37
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Условие
Ватсон поставил Рыбке простую задачу - найти сумму чисел меньших N, которые должны делиться или на A, или на B, и вывести ее остаток от деления на 1000000007 (10^9 + 7). Помогите Рыбке справиться с этой задачей.

Входные данные
В одной строке заданы три целых числа N, A и .
1 <= N, A, B < 10^18.

Выходные данные
Рассчитать остаток от деления необходимой суммы на 1000000007.

Пример
Вход: 7 2 3
Вывод: 15

Пояснение
Числа, которые делятся на 2: 2, 4, 6. Числа, которые делятся на 3: 3, 6.
Сумма этих чисел: 2 + 3 + 4 + 6 = 15

Мое решение:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
using namespace std;
 
int main(void)
{
    long long n, a, b, sum = 0;
    cin>>n>>a>>b;
 
    for (long long i = a; i < n; i += a) if (i % b != 0) sum += i;
    for (long long i = b; i < n; i += b) sum += i;
 
    cout<<(sum % 1000000007);
    return 0;
}
На 53 тесте превысило лимит времени 500 мс

Как еще больше оптимизировать?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
20.04.2013, 18:22
Ответы с готовыми решениями:

Задача паскаль-сумма всех двузначных чисел, которые делятся на 3 и не делятся на 4
Составьте программу вычисления суммы всех двузначных чисел, которые делятся на 3 и не делятся на 4.

Вычислить сумму целых чисел, меньших 1000, которые делятся на 3 или на 7
if ((i % 3 == 0) || (i % 7 == 0)) sum += i; а тут? Разработать программу вычисляющую сумму всех целых чисел, меньших 1000, которые...

Сумма 2-х чисел, которые делятся на 3 или 7 или на оба сразу
Помогите пожалуйста, кто может. Требуется: Написать базу, которая будет выдавать все возможные подстановки: то есть если цель ...

37
 Аватар для dr.curse
404 / 360 / 36
Регистрация: 11.10.2010
Сообщений: 1,907
20.04.2013, 21:33
Студворк — интернет-сервис помощи студентам
а так?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
int main()
{
    long long n,a,b,sa,sb,sab,c,cc;
    scanf("%lld%lld%lld",&n,&a,&b);
    c=(n/a)*a;
    cc=(a+c)/a-1;
    sa=(a+c)*cc/2;
    c=(n/b)*b;
    cc=(b+c)/b-1;
    sb=(b+c)*cc/2;
    a=a*b;
    c=(n/a)*a;
    cc=(a+c)/a-1;
    sab=(a+c)*cc/2;
    printf("%lld",sa+sb-sab);
    return 0;
}
0
C#
57 / 57 / 5
Регистрация: 09.03.2013
Сообщений: 216
20.04.2013, 21:35  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
вполне возможно писал на коленке
какие данные
напиши проверю
А рапортов нет... Вот в чем вся прелесть олимпиадных задач
Помню, 150 6 7 должно давать 3315. Руками утром считал.

Добавлено через 1 минуту
Цитата Сообщение от aram_gyumri Посмотреть сообщение
а так?
То же самое.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,878
20.04.2013, 21:35
Цитата Сообщение от A1exSun Посмотреть сообщение
У меня были проблемы со вторым тестом, когда я учитывал последний элемент последовательности (в общем, <= вместо < в цикле).
стоп а если N делится на A (B) то так и будет
тогда нужно сделать так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 int summA,int summB,int summAB,summ;
int qA=n/A;
if(n%A==0)
 qA--;
int lastA =qA*A;
summA=((A+lastA)*qA)/2;
 
int qB=n/B;
if(n%B==0)
 qB--;
int lastB =qB*B;
summB=((B+lastB)*qB)/2;
 
int qAB=n/(A*B);
if(n%(A*B)==0)
 qAB--;
int lastAB =qAB*A*B;
summAB=((A*B+lastAB)*qAB)/2;
 
summ=summA+summB-summAB;
0
 Аватар для dr.curse
404 / 360 / 36
Регистрация: 11.10.2010
Сообщений: 1,907
20.04.2013, 21:35
у меня правильный ответ выдает на твой тест
0
C#
57 / 57 / 5
Регистрация: 09.03.2013
Сообщений: 216
20.04.2013, 21:37  [ТС]
Цитата Сообщение от aram_gyumri Посмотреть сообщение
у меня правильный ответ выдает на твой тест
Да я уже проверил, сходится...
Не знаю в чем прикол. У меня было когда лишнее считал.
Мой код проходит 53 теста, снова проверял чтоб убедиться не сломалось ли ничего там.
0
 Аватар для dr.curse
404 / 360 / 36
Регистрация: 11.10.2010
Сообщений: 1,907
20.04.2013, 21:38
Цитата Сообщение от ValeryS Посмотреть сообщение
стоп а если N делится на A (B) то так и будет
тогда нужно сделать так
да действительно а я просто из всех 1 вычитал поскольку проверял только тест 10 2 5
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,878
20.04.2013, 21:59
вот код
объеденены два подхода твой и мой

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "stdafx.h"
#include <iostream>
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
 long long n, a, b, sum = 0;
    cin>>n>>a>>b;
 
    for (long long i = a; i < n; i += a) if (i % b != 0) sum += i;
    for (long long i = b; i < n; i += b) sum += i;
    cout<<endl;
    cout<<(sum % 1000000007)<<endl;
  long long summA,summB,summAB,summ;
 long long qA=n/a;
if(n%a==0)
 qA--;
 long long lastA =qA*a;
summA=((a+lastA)*qA)/2;
 
 long long qB=n/b;
if(n%b==0)
 qB--;
 long long lastB =qB*b;
summB=((b+lastB)*qB)/2;
 
 long long qAB=n/(a*b);
if(n%(a*b)==0)
 qAB--;
 long long lastAB =qAB*a*b;
summAB=((a*b+lastAB)*qAB)/2;
 
summ=summA+summB-summAB;
 
 cout<<(summ % 1000000007)<<endl;   
 return 0;
}
а вот ответы
первый твой второй мой
6000
2
3

11997000
11997000
150
7
6

3165
3165
7
2
3

15
15
как видишь равны
0
_
317 / 151 / 27
Регистрация: 08.10.2011
Сообщений: 432
20.04.2013, 22:07
valerys,aram, там числа очень большие могут быть и суммы не влезут в long long
0
C#
57 / 57 / 5
Регистрация: 09.03.2013
Сообщений: 216
20.04.2013, 22:13  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
а вот ответы
первый твой второй мой

как видишь равны
Я не знаю, почему мой код проходит, твой нет. Позже может быть дадут логи проверок, там видно будет.

Добавлено через 24 секунды
Цитата Сообщение от ya_noob Посмотреть сообщение
valerys,aram, там числа очень большие могут быть и суммы не влезут в long long
У меня же влезли.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,878
20.04.2013, 22:19
Цитата Сообщение от ya_noob Посмотреть сообщение
valerys,aram, там числа очень большие могут быть и суммы не влезут в long long
а в тупом цикле влезут???
самое большое что может быть это число 10^18 A=1
тогда сумма будет где то 10^36

и вообще я идею дал думайте сами

Добавлено через 2 минуты
Цитата Сообщение от A1exSun Посмотреть сообщение
Я не знаю, почему мой код проходит, твой нет.
А ты уже правленый пробовал??
в смысле с учетом того что N кратное A(B)?
0
Higher
 Аватар для diagon
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
20.04.2013, 22:25
Как-то так, по формуле включений-исключений.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
 
int foo(long long x, long long n, int modulo)
{
    long long first = x;            //первый член арифметической прогрессии
 
    long long last = (n / x * x);   //последний член арифметической прогресии
 
    long long count  = n / x;       //количество членов в арифметической прогрессии
 
    return ( ( ( (first % modulo + last % modulo) % modulo) * (count % modulo) ) / 2 ) % modulo;
}
 
int main()
{
    const int modulo = 1000000007;
    
    long long n;
 
    std::cin >> n;
    
    long long a, b;
    
    std::cin >> a >> b;
 
    std::cout << (foo(a, n, modulo) - foo(a * b, n, modulo) + foo(b, n, modulo)) % modulo << std::endl; 
}
0
_
317 / 151 / 27
Регистрация: 08.10.2011
Сообщений: 432
20.04.2013, 22:38
valerys, переполнение это одна из проблем. что касается неправильного резульрата, то попробуйте протестировать свою программу при а=2 и b=4. что получится?

Добавлено через 6 минут
вычитать нужно не сумму для a*b, а сумму для нок(аb)
0
Higher
 Аватар для diagon
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
20.04.2013, 22:43
Цитата Сообщение от ya_noob Посмотреть сообщение
вычитать нужно не сумму для a*b, а сумму для нок(аb)
Кстати да, тут я поспешил.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,878
20.04.2013, 22:49
Цитата Сообщение от ya_noob Посмотреть сообщение
valerys, переполнение это одна из проблем. что касается неправильного резульрата,
не надо мне за переполнения рассказывать
я тебя спрашивал почему здесь

Цитата Сообщение от ValeryS Посмотреть сообщение
summA=((a+lastA)*qA)/2;
Будет переполнение
а здесь
Цитата Сообщение от A1exSun Посмотреть сообщение
for (long long i = b; i < n; i += b) sum += i;
нет?


Цитата Сообщение от ya_noob Посмотреть сообщение
вычитать нужно не сумму для a*b,
это я уже понял на тесте 123 12 15

Цитата Сообщение от ya_noob Посмотреть сообщение
а для нок(аb)
не совсем нок
нок дла 12 и 15 =3
а вычитать нужно 60 и 120
т.е
сумма должна быть для такого ряда
A*B/нок ........ (A*B/нок)*k;
сейчас думаю как быстро найти нок

Добавлено через 1 минуту
diagon, да я тоже в это вперся
как то числа были заданы 3 2 и 6 7
у них нет общих делителей
0
_
317 / 151 / 27
Регистрация: 08.10.2011
Сообщений: 432
20.04.2013, 22:56
я всё правильно написал, именно нок, а вы путаете его с нод
0
Higher
 Аватар для diagon
1953 / 1219 / 120
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
20.04.2013, 23:00
С учетом того, что пересечением является нок, будет как-то так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
 
int foo(long long x, long long n, int modulo)
{
    long long first = x;            //первый член арифметической прогрессии
 
    long long last = (n / x * x);   //последний член арифметической прогресии
 
    long long count  = n / x;       //количество членов в арифметической прогрессии
 
    return ( ( ( (first % modulo + last % modulo) % modulo) * (count % modulo) ) / 2 ) % modulo;
}
 
template <class T>
T gcd(T a, T b)
{
    while (a ^= b ^= a ^= b %= a);
    return b;
}
 
template <class T>
T lcm(T a, T b)
{
    return a * b / gcd(a, b);
}
 
int main()
{
    const int modulo = 1000000007;
    
    long long n;
 
    std::cin >> n;
    
    long long a, b;
    
    std::cin >> a >> b;
 
    std::cout << (foo(a, n, modulo) - foo(lcm(a, b), n, modulo) + foo(b, n, modulo)) % modulo << std::endl; 
}
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,878
20.04.2013, 23:05
вот исправленая версия
тестируйте
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "stdafx.h"
#include <iostream>
 
using namespace std;
long long NOK(long long A,long long B)
{
if(A%2==0&&B%2==0)
 return 2;
long long c=A;
if(A>B)
  c=B;
for(int i=3;i<c/2;c+=2)
{
 if(A%i==0&&B%i==0)
     return i;
}
return 1;
 
 
}
 
int _tmain(int argc, _TCHAR* argv[])
{
 long long n, a, b, sum = 0;
    cin>>n>>a>>b;
 
    for (long long i = a; i < n; i += a) if (i % b != 0) sum += i;
    for (long long i = b; i < n; i += b) sum += i;
    cout<<endl;
    cout<<(sum % 1000000007)<<endl;
  long long summA,summB,summAB,summ;
  
  
  
  long long qA=n/a;
if(n%a==0)
 qA--;
 long long lastA =qA*a;
summA=((a+lastA)*qA)/2;
 
 long long qB=n/b;
if(n%b==0)
 qB--;
 long long lastB =qB*b;
summB=((b+lastB)*qB)/2;
 
long long nok=NOK(a,b); 
long long first=a*b/nok;
 
long long qAB=n/first;
if(n%first==0)
 qAB--;
long long lastAB =qAB*first;
summAB=((first+lastAB)*qAB)/2;
 
summ=summA+summB-summAB;
 
 cout<<(summ % 1000000007)<<endl;   
 return 0;
}
Добавлено через 1 минуту
Цитата Сообщение от ya_noob Посмотреть сообщение
я всё правильно написал, именно нок, а вы путаете его с нод
ну попутал с кем не бывает
я твоего варианта не вижу

Добавлено через 1 минуту
diagon,
проверь свой вариант
если A равно B
мой врет
причем оба метода
я так понимаю 0 должен быть
0
_
317 / 151 / 27
Регистрация: 08.10.2011
Сообщений: 432
20.04.2013, 23:10
я с телефона пишу. думаю на набор программы вся ночь уйдет
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
20.04.2013, 23:10

Определите, каких чисел в массиве больше: которые делятся на первый или которые делятся на последний элемент
Определите, каких чисел в массиве больше: которые делятся на первый элемент массива или которые делятся на последний элемент массива.

Определите, каких чисел в массиве больше: которые делятся на первый элемент массива или которые делятся на последний эле
Определите, каких чисел в массиве больше: которые делятся на первый элемент массива или которые делятся на последний элемент массива

количество натуральных чисел, меньших 50, которые не делятся на 11.
плиииззззз, помогите решить 2 задачи по паскалю... 1) определить количество натуральных чисел, меньших 50, которые не делятся на 11. ...

Определить количество чисел, меньших n, которые не делятся на 11
Не знаю как решить. Определить количество натуральных чисел меньших n. Которые не делятся на 11. Протестировать на n=10, n=100,n =1000.

Множество целых чисел, принадлежащих отрезку [980; 5320], которые делятся на 4 или на 5 и не делятся на 11, 17, 19 и 23
Рассматривается множество целых чисел, принадлежащих отрезку , которые делятся на 4 или на 5 и не делятся на 11, 17, 19 и 23. Найдите...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
38
Ответ Создать тему
Новые блоги и статьи
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru