1. 程式人生 > >2017北大校賽 J題 pairs

2017北大校賽 J題 pairs

預處理 常數 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(int
p = 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