2017北大校赛 J题 pairs
Posted Saurus
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017北大校赛 J题 pairs相关的知识,希望对你有一定的参考价值。
题目链接 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的主要内容,如果未能解决你的问题,请参考以下文章