Good Bye 2018 C

Whiteying

2018-12-31 02:23:34

Personal

# 题目链接: https://codeforces.com/contest/1091/problem/C # 原题: **Problem Statement** There are n people sitting in a circle, numbered from 1 to n in the order in which they are seated. That is, for all i from 1 to n−1, the people with id i and i+1 are adjacent. People with id n and 1 are adjacent as well. The person with id 1 initially has a ball. He picks a positive integer k at most n, and passes the ball to his k-th neighbour in the direction of increasing ids, that person passes the ball to his k-th neighbour in the same direction, and so on until the person with the id 1 gets the ball back. When he gets it back, people do not pass the ball any more. For instance, if n=6 and k=4, the ball is passed in order [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. Find and report the set of possible fun values for all choices of positive integer k. It can be shown that under the constraints of the problem, the ball always gets back to the 1-st player after finitely many steps, and there are no more than 105 possible fun values for given n. **Input** The only line consists of a single integer n (2≤n≤109) — the number of people playing with the ball. **Output** Suppose the set of all fun values is f1,f2,…,fm. Output a single line containing m space separated integers f1 through fm in increasing order. **Examples** **input1** 6 **output1** 1 5 9 21 **input2** 16 **output2** 1 10 28 64 136 **Note** In the first sample, we've already shown that picking k=4 yields fun value 9, as does k=2. Picking k=6 results in fun value of 1. For k=3 we get fun value 5 and with k=1 or k=5 we get 21. ![](https://codeforces.com/predownloaded/cf/a9/cfa92b3228335c77776143e8991a2c9a96a0cbe9.png) In the second sample, the values 1, 10, 28, 64 and 136 are achieved for instance for k=16, 8, 4, 10 and 11, respectively. ------------ # 题意: n个人围成一个圈,进行传球,每次的规则都是只能传到第k个人,只到传回第一个人手中结束,传到的人的编号被计成一个数,求有多少种不同的数,并按从小到大的顺序输出这些数。 # 思路: 从小的数据进行分析,发现素数只有两个解,再由一些2的倍数的数有某些规律,加上数据有1e9这么大,想到O(N)算法肯定不可能的。 由此我们想到素数的因子只有1和他的本身,可以由因子出发,找到这个数的全部因子,将这个数除以某一个因子,就是k=这个因子,的时候,所有传到的人的编号总和。 # AC代码: ``` #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<cmath> #include<set> typedef long long ll; #include<vector> #define cin(n) scanf("%lld",&(n)) #define cout(n) printf("%lld",(n)) #define couc(c) printf("%c",(c)) #define coutn printf("\n") #define cout_ printf(" ") #define debug() printf("haha\n") const int MAXN =10000005; ll t,n,k; ll a[MAXN]; ll ansa,ansb; ll MIN=0x3f3f3f3f; ll ans; std::set<ll> s; int ansnum=1; ll arr[1000005] = {1}; int factor(ll n) { int count = 1, num = sqrt(n); for (int i = 2; i <= num; i++) { if ((n % i == 0) && (n != i * i)) { arr[count++] = i; arr[count++] = n / i; } } if (n == (num*num)) arr[count++] = num; return count; } int main() { cin(n); int cnt=factor(n); printf("1 "); for(int i=cnt-1;i>=0;i--) { s.insert((n/arr[i])+(((n/arr[i])*((n/arr[i])-1))/2)*arr[i]); } std::set<ll>::iterator iter; for(iter = s.begin() ; iter != s.end() ; ++iter) { std::cout<<*iter<<" "; } return 0; } ```