SRM500 Div2 Hard(1000) GeometricProgressions
積なので素因数分解が簡単に計算できる。素因数の個数を覚えておく。コメントアウトのように書いたらメモリ不足で落ちた。b2*q22以降は、b2*q21と異なりS1に含まれないものの個数を数えるだけにしたら通った。
#include <set> #include <map> using namespace std; // 素因数分解 map<int,int>fact( int n ) { map<int,int>r; int p=2; while(p*p<=n) if(n%p==0)r[p]++,n/=p; else p++; if(n>1)r[n]++; return r; } class GeometricProgressions{public: int count( int b1, int q1, int n1, int b2, int q2, int n2 ) { map<int,int> f0; f0[0] = -1; // 0を表す map<int,int> b1f = b1>0 ? fact(b1) : f0; map<int,int> q1f = q1>0 ? fact(q1) : f0; map<int,int> b2f = b2>0 ? fact(b2) : f0; map<int,int> q2f = q2>0 ? fact(q2) : f0; set<map<int,int> > S; S.insert(b1f); for ( int i=1; i<n1; i++ ) { if ( b1f!=f0 && q1f!=f0 ) for ( map<int,int>::iterator it=q1f.begin(); it!=q1f.end(); it++ ) b1f[it->first] += it->second; else b1f = f0; S.insert(b1f); } S.insert(b2f); int c = 0; map<int,int> b2f1; for ( int i=1; i<n2; i++ ) { if ( b2f!=f0 && q2f!=f0 ) for ( map<int,int>::iterator it=q2f.begin(); it!=q2f.end(); it++ ) b2f[it->first] += it->second; else b2f = f0; if ( i==1 ) S.insert(b2f), b2f1 = b2f; else if ( b2f!=b2f1 && S.count(b2f)==0 ) c++; } return (int)S.size() + c; /* S.insert(b2f); for ( int i=1; i<n2; i++ ) { if ( b2f!=f0 && q2f!=f0 ) for ( map<int,int>::iterator it=q2f.begin(); it!=q2f.end(); it++ ) b2f[it->first] += it->second; else b2f = f0; S.insert(b2f); } return (int)S.size(); */ }};