Good Bye 2018 C. New Year and the Sphere Transmission(数学)

探讨在圆形人群中传递球的数学游戏,通过选择特定步长传递球,目标是找出所有可能的趣味值,即触球人群编号之和,利用等差数列求和公式解决复杂问题。

题目链接:C. New Year and the Sphere Transmission

There are n n n people sitting in a circle, numbered from 1 1 1 to n n n in the order in which they are seated. That is, for all i i i from 1 1 1 to n − 1 n-1 n1, the people with id i i i and i + 1 i+1 i+1 are adjacent. People with id n n n and 1 1 1 are adjacent as well.

The person with id 1 1 1 initially has a ball. He picks a positive integer k k k at most n n n, and passes the ball to his k k k-th neighbour in the direction of increasing ids, that person passes the ball to his k k k-th neighbour in the same direction, and so on until the person with the id 1 1 1 gets the ball back. When he gets it back, people do not pass the ball any more.

For instance, if n = 6 n = 6 n=6 and k = 4 k = 4 k=4, the ball is passed in order [ 1 , 5 , 3 , 1 ] [1, 5, 3, 1] [1,5,3,1].

Consider the set of all people that touched the ball. The fun value of the game is the sum of the ids of people that touched it. In the above example, the fun value would be 1 + 5 + 3 = 9 1 + 5 + 3 = 9 1+5+3=9.

Find and report the set of possible fun values for all choices of positive integer k k k. It can be shown that under the constraints of the problem, the ball always gets back to the 1 1 1-st player after finitely many steps, and there are no more than 1 0 5 10^5 105 possible fun values for given n n n.

Input

The only line consists of a single integer n n n ( 2 ≤ n ≤ 1 0 9 2 \leq n \leq 10^9 2n109) — the number of people playing with the ball.

Output

Suppose the set of all fun values is f 1 , f 2 , … , f m f_1, f_2, \dots, f_m f1,f2,,fm.

Output a single line containing m m m space separated integers f 1 f_1 f1 through f m f_m fm in increasing order.

Examples

Input

6

Output

1 5 9 21

Input

16

Output

1 10 28 64 136

Note

In the first sample, we’ve already shown that picking k = 4 k = 4 k=4 yields fun value 9 9 9, as does k = 2 k = 2 k=2. Picking k = 6 k = 6 k=6 results in fun value of 1 1 1. For k = 3 k = 3 k=3 we get fun value 5 5 5 and with k = 1 k = 1 k=1 or k = 5 k = 5 k=5 we get 21 21 21.

In the second sample, the values 1 1 1, 10 10 10, 28 28 28, 64 64 64 and 136 136 136 are achieved for instance for k = 16 k = 16 k=16, 8 8 8, 4 4 4, 10 10 10 and 11 11 11, respectively.

思路

n n n个数围成一个环,编号是从 1 1 1 n n n ,现在你可以随意选择一个不超过 n n n的数 k k k,从 1 1 1开始,按照环上字符增大的顺序,每隔 k k k个选择一个数字,直到回到起点 1 1 1,然后计算出路径上不同数字的和,记为fun value,题目给出你一个数 n n n,然后让你求出这 n n n个数的所有的fun value,从小到大输出结果。

如果选择的 k k k n n n的因数,那么一定可以一轮就走完,不同的因数,获得的fun value的值也不一样。

当选择的 k k k不是 n n n的因数时,那么一轮一定走不完,然后直到某一轮走的路径正好和 k k k n n n的因数的某一条路径重合,所以我们计算 k k k n n n的因数的路径时,已经把这种情况包含了。

所以,利用等差数列求和公式 S n = n ( a 1 + a n ) 2 S_n=\frac{n(a_1+a_n)}{2} Sn=2n(a1+an)可以计算出结果。第一项一定为 1 1 1,数字的个数就是当前枚举的 i i i或者 n i \frac{n}{i} in.

可以打个表验证一下:

打表代码
#include <bits/stdc++.h>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
typedef long long ll;
int get_x(int n, int x)
{
    if (x == n)
        return 1;
    int s = x, sum = x + 1;
    while (s != 0)
    {
        s = (s + x) % n;
        sum += (s + 1);
    }
    return sum;
}
set<int> getall_n(int n)
{
    set<int> s;
    for (int i = 1; i <= n; i++)
        s.insert(get_x(n, i));
    return s;
}
int main()
{
    for (int i = 1; i <= 100; i++)
    {
        printf("n=%d:\n", i);
        set<int> s = getall_n(i);
        for (auto x : s)
            printf("%d ", x);
        printf("\n");
    }
    return 0;
}

然后印证了我们的观点,每个数的答案个数就是他的因子个数。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
set<ll> s;
int main()
{
    ll n;
    scanf("%lld", &n);
    for (ll i = 1; i * i <= n; i++)
    {
        if (n % i == 0)
        {
            ll x = n / i;
            s.insert((1 + n - i + 1) * x / 2);
            s.insert((1 + n - x + 1) * i / 2);
        }
    }
    for (auto x : s)
        printf("%lld ", x);
    puts("");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值