2017北大校賽 J題 pairs
阿新 • • 發佈:2017-05-29
預處理 常數 cout pair 北大 一道 ace http cto
題目鏈接 http://poj.openjudge.cn/practice/C17J/
orz 原來是一道無腦枚舉題目
只是很卡常數而已
復雜度算錯也是很醉orz
當時怎麽沒想著優化常數呢
題解:枚舉x,p,y,就可以了
當然,普通暴力枚舉肯定會超時,復雜度是M^1.5
(一開始算的是M^1.5logM,實際上算錯了,因為M + M/4 + M/9 + .... 不超過2*M)
我們考慮預處理一些部分,其實就是預處理出每個數i的小於sqrt(i)的所有約數
這個復雜度實際上是MlogM
之後我們再暴力枚舉,枚舉y的時候直接枚舉約數,可以優化很大的常數
同時要感謝ljw神犇orz,指出了我復雜度計算上的錯誤
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <vector> #define pb push_back using namespace std; int T, M, ans; int f[800000]; vector<int> V[800001]; int main(){ cin>>T; for(int i = 1; i <= 800000; i++) V[i].pb(1); for(int i = 2; i <= sqrt(800000)+0.5; i++){ for(int j = 1; j*i <= 800000; j++){ V[j*i].pb(i); } } while(T--){ ans = 0; cin>>M; int _ = sqrt(M) + 0.5; for(int x = 1; x <= _; x++){ memset(f, 0, sizeof(f)); for(intp = 1; p <= M/x/x; p++){ int t = M - p*x*x; if(t <= 0) break; for(int i = 0; i < V[t].size(); i++){ int y = V[t][i]; if(!f[y]) { f[y] = 1; ans++; } if(!f[t/y]) { f[t/y] = 1; ans++; } } } } cout<<ans<<endl; } }
2017北大校賽 J題 pairs