Description
话说, 小X是个数学大佬,他喜欢做数学题。有一天,小X想考一考小Y。他问了小Y一道数学题。题目如下:
对于一个正整数N,存在一个正整数T(0<T<N),使得
的值是正整数。
小X给出N,让小Y给出所有可能的T。如果小Y不回答这个神奇的大佬的简单数学题,他学神的形象就会支离破碎。所以小Y求你帮他回答小X的问题。
对于一个正整数N,存在一个正整数T(0<T<N),使得
的值是正整数。
小X给出N,让小Y给出所有可能的T。如果小Y不回答这个神奇的大佬的简单数学题,他学神的形象就会支离破碎。所以小Y求你帮他回答小X的问题。
Input
一个整数N。
Output
第一个数M,表示对于正整数N,存在M个不同的正整数T,使得
是整数。
后面是M个数,每一个数代表可能的正整数T(按从小到大的顺序排列)。
是整数。
后面是M个数,每一个数代表可能的正整数T(按从小到大的顺序排列)。
Sample Input
Sample Input1: 1 Sample Input2: 3 Sample Input3 180
Sample Output
Sample Output 0 Sample Output 1 2 Sample Output 5 120 144 160 168 176
Data Constraint
对于5%的数据,N=1.
对于20%的数据,N<=5.
对于40%的数据,N<=1000000
对于另外20%的数据,答案只有1个,且N为质数,保证对于前60%的数据,当N为质数的时候,答案都一定只有一个,对于这20%的数据,满足2<N。
对于80%的数据,N<=10^9.
对于100%的数据,N<=10^14.
对于20%的数据,N<=5.
对于40%的数据,N<=1000000
对于另外20%的数据,答案只有1个,且N为质数,保证对于前60%的数据,当N为质数的时候,答案都一定只有一个,对于这20%的数据,满足2<N。
对于80%的数据,N<=10^9.
对于100%的数据,N<=10^14.
233考场打的大暴力拿了65分。
既没有判断素数又没有打表,竟然暴力拿这么多分真是不敢相信。
放上考场yy代码:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <algorithm> using namespace std; #define int long long inline int read() { int res=0;char c=getchar();bool f=0; while(!isdigit(c)) {if(c=='-')f=1;c=getchar();} while(isdigit(c))res=(res<<3)+(res<<1)+(c^48),c=getchar(); return f?-res:res; } int tmp[10000005], cnt; signed main(){ freopen("math.in", "r", stdin); freopen("math.out", "w", stdout); int n = read(); if (n == 1) return puts("0"), 0; int ans = 0; if (n <= 6e7) { for (register int i = 1 ; i < n ; i ++) if ((n - i / 2) % (n - i) == 0 and (i % 2) == 0) tmp[++ans] = i; printf("%lld ", ans); for (register int j = 1 ; j <= ans ; j ++) printf("%lld ", tmp[j]); return 0; } int tt = n - 3 * sqrt(n); tt = max(tt, (int)0); if (tt % 2 == 1) tt--; for (register int i = tt ; i < n ; i += 2) if ((n - i / 2) % (n - i) == 0) tmp[++ans] = i; printf("%lld ", ans); for (register int i = 1 ; i <= ans ; i ++) printf("%lld ", tmp[i]); return 0; }
其实它给的暴力分是40分(逃。。
然后聊聊正解233.
设...算了不写了233.
放个网址就跑题解
然后有不少细节要注意,比如枚举i的时候一定要判断是不是奇数,和最后答案是不是奇数。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define int long long inline int read() { int res=0;char c=getchar();bool f=0; while(!isdigit(c)) {if(c=='-')f=1;c=getchar();} while(isdigit(c))res=(res<<3)+(res<<1)+(c^48),c=getchar(); return f?-res:res; } int tmp[2*10000005], cnt; signed main() { int n = read(); n <<= 1; int ans = 0; for (register int i = 2 ; i <= sqrt(n) ; i ++) { if (n % i == 0) { if (i % 2 == 1) tmp[++ans] = n / i * max(((i - 1) / 2), (int)1); int t = n / i; if (i != t and t % 2 == 1) tmp[++ans] = n / t * max(((t - 1) / 2), (int)1); } } int tt = ans; sort(tmp + 1, tmp + 1 + ans); for (register int i = 1 ; i <= tt ; i ++) if (tmp[i] % 2 == 1) tmp[i] = 0, ans--; printf("%lld ", ans); for (register int i = 1 ; i <= tt ; i ++) if(tmp[i]) printf("%lld ", tmp[i]); return 0; }