백준17134 르모앙의 추측 작성일 2019-11-10 | In PS 문제 링크 http://icpc.me/17134 사용 알고리즘 FFT 풀이 누가 봐도 FFT 문제입니다. 시간 제한도 널널하므로 세미 소수만 잘 판별해준다면 쉽게 풀 수 있습니다. 전체 코드 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869#define _USE_MATH_DEFINES #include <bits/stdc++.h> using namespace std; typedef complex<double> cpx; const int SZ = 1 << 21; void FFT(cpx f[], bool inv = false){ int n = SZ; for(int i = 1, j = 0; i < n; ++i){ int b = n/2; while(!((j ^= b) & b)) b /= 2; if(i < j) swap(f[i], f[j]); } for(int k = 1; k < n; k *= 2){ double a = (inv ? M_PI/k : -M_PI/k); cpx w(cos(a), sin(a)); for(int i = 0; i < n; i += k*2){ cpx wp(1, 0); for(int j = 0; j < k; ++j){ cpx x = f[i+j], y = f[i+j+k] * wp; f[i+j] = x + y; f[i+j+k] = x - y; wp *= w; } } } if(inv){ for(int i = 0; i < n; ++i) f[i] /= n; } } void pw(cpx f[], cpx g[]){ FFT(f); FFT(g); for(int i=0; i<SZ; i++) f[i] *= g[i]; FFT(f, 1); } int chk[SZ/2]; cpx f[SZ], g[SZ]; int main(){ ios_base::sync_with_stdio(0); cin.tie(0); //cout << time(NULL) << "\n"; chk[0] = chk[1] = 1; for(long long i=2; i<1000000; i++){ if(chk[i]) continue; if(i % 2 == 1) f[i] = cpx(1, 0); for(int j=i+i; j<1000000; j+=i){ chk[j]++; if(j/i%i == 0){ chk[j]++; if(j/i/i%i == 0) chk[j]++; } } } for(int i=2; i<=1000000; i+=2){ if(chk[i] == 2) g[i] = cpx(1, 0); } pw(f, g); int t; cin >> t; while(t--){ int x; cin >> x; cout << round(f[x].real()) << "\n"; } //cout << time(NULL) << "\n"; }