codeforces Good Bye 2018 C. New Year and the Sphere Transmission(数学 ,贝祖定理/群论)

C. New Year and the Sphere Transmission

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

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

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

For instance, if n=6n=6 and k=4k=4, the ball is passed in order [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=91+5+3=9.

Find and report the set of possible fun values for all choices of positive integer kk. It can be shown that under the constraints of the problem, the ball always gets back to the 11-st player after finitely many steps, and there are no more than 105105 possible fun values for given nn.

Input

The only line consists of a single integer nn (2≤n≤1092≤n≤109) — the number of people playing with the ball.

Output

Suppose the set of all fun values is f1,f2,…,fmf1,f2,…,fm.

Output a single line containing mm space separated integers f1f1 through fmfm in increasing order.

Examples

input

Copy

6

output

Copy

1 5 9 21

input

Copy

16

output

Copy

1 10 28 64 136

Note

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

In the second sample, the values 11, 1010, 2828, 6464 and 136136 are achieved for instance for k=16k=16, 88, 44, 1010 and 1111, respectively.

 

题目大意:

给出整数n个连续的数1~n,成环排列,从1开始跳,每次可以跳1、2、3......步,计算出所有步数条件下从1开始再跳回到1所经过的数集的数之和。

思路:

官方题解用的最本质的贝祖定理,然后自己突发奇想可以将题目所描述的条件抽象成一个n阶同余加群,方便起见,我们将n个数全部减一,群的幺元为起点元素0,生成元之一为元素1,我们从1~n中任取一个元素k,显然,由该元素可以一个循环子群,且该子群所包含的元素就是我们想要求得的每次跳某一步数(k步)条件下从一出发再到一结束的元素们。考虑群的性质,其子群的阶数只能是n的因子数,且一定包含幺元“0”,所以我们可以枚举每一个子群,同时用等差数列求和公式求和该步数下所经过的元素之和。枚举子群我们可以枚举子群的阶数1~n,如果i能够被n整除,说明有这么一个阶数为i的子群,然后其对应的步数(等差求和的d)正好对应(考虑了起点0/1的问题)该子群生成元所代表的值。该生成元的值=群的生成元1^(n/对应子群阶数i)。最后,我们可以得到一个o(\sqrt{n})的算法。

AC代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include<algorithm>
#include <set>
#include <queue>
#include <stack>
#include<vector>
#include<map>
#include<ctime>
#define ll long long
using namespace std;
ll ans[110000];
int main()
{
    ll n;
    while(cin>>n)
    {
        memset(ans,0,sizeof(ans));
        int tot=0;
        ll sum=0;
        for(int i=1;i*i<=n;++i)
        {
            if(n%i==0)
            {
                ll nn=n/i;
                ans[++tot]=nn+nn*(nn-1)/2*i;//这里考虑a1=1;
                ans[++tot]=i+i*(i-1)/2*nn;
            }
        }
        ll pre=-1;
        sort(ans+1,ans+1+tot);
        for(int i=1;i<=tot;++i)
        {
            if(pre!=ans[i])//去重
            {
                cout<<ans[i]<<" ";
                pre=ans[i];
            }
        }
        cout<<endl;
    }
    return 0;
}

 

 

The end;

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值