DIV2 1000pt

题意:给定两个集合A和B,A = {b1*q1i | 0 <= i <= n1-1},B = {b2*q2i | 0 <= i <= n2-1},问将AB两个集合合并之后的集合中元素的个数。(注意,每个集合中每个元素只能有一个)。其中0 <= b1,b2,q1,q2 <= 5*10^8,1 <= n1,n2 <= 10^5。

解法:首先,我们称b = 0或者q = 0或者q = 1的集合为特殊集合,因为特殊集合中最多有两个元素。若至少有一个集合为特殊集合,则此问题容易解决。下面考虑两个集合都不为特殊集合的情况。

   其实,如果不是A和B中的数太大,我们可以将他们每个都求出来,然后放到一个set<long long>里面,返回set.size()即可,时间复杂度O(n1 + n2)。我们需要找到一种表示这些大数的方法。考虑整数的唯一分解式。

   每个整数可以表示成(a1^p1) * (a2^p2) * (a3^p3) *..* (ak^pk)的形式,也就是说,我们只需要统一所有会用到的质数,然后把p1,p2..pk放到一个vector里面,就可以表示每个整数。然后用一个set<vector<long long> >即可统计元素的个数。

tag: math, set

 // BEGIN CUT HERE
/*
* Author: plum rain
* score :
*/
/* */
// END CUT HERE
#line 11 "GeometricProgressions.cpp"
#include <sstream>
#include <stdexcept>
#include <functional>
#include <iomanip>
#include <numeric>
#include <fstream>
#include <cctype>
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <set>
#include <queue>
#include <bitset>
#include <list>
#include <string>
#include <utility>
#include <map>
#include <ctime>
#include <stack> using namespace std; #define CLR(x) memset(x, 0, sizeof(x))
#define PB push_back
#define SZ(v) ((int)(v).size())
#define zero(x) (((x)>0?(x):-(x))<eps)
#define out(x) cout<<#x<<":"<<(x)<<endl
#define tst(a) cout<<#a<<endl
#define CINBEQUICKER std::ios::sync_with_stdio(false) typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<double> VD;
typedef long long int64; const double eps = 1e-;
const double PI = atan(1.0)*;
const int maxint = ;
const int N = ;
const int M = ; int an[][N];
int tmp_sz;
int64 bn[][N]; int inte_dev(int x, int* an, int64* bn)
{
int all = -;
for (int i = ; i*i <= x;){
if (!(x%i)){
an[++all] = i;
bn[all] = ;
}
while (!(x%i)){
++ bn[all];
x /= i;
}
if (i == ) ++ i;
else i += ;
}
++ all;
if (x != ){
an[all] = x;
bn[all++] = ;
}
return all;
} int gao(int64 x, int a)
{
int ret = ;
while (!(x % a)){
x /= a;
++ ret;
}
return ret;
} VI vadd(VI a, VI b)
{
VI ret; ret.clear();
for (int i = ; i < tmp_sz; ++ i)
ret.PB (a[i]+b[i]);
return ret;
} class GeometricProgressions
{
public:
int count(int aa, int b, int n, int c, int d, int m){
int64 a[];
a[] = aa; a[] = b; a[] = c; a[] = d;
if (!a[] || !a[] || a[] == ){
swap (a[], a[]); swap (a[], a[]); swap (n, m);
}
if (!a[] || !a[] || a[] == ){
set<int64> tmp;
tmp.insert(a[]);
if (n > ) tmp.insert(a[]*a[]); int cnt = , sz_tmp = tmp.size();
int64 now = a[];
for (int i = ; i < m; ++ i){
if (tmp.count(now)) ++ cnt;
else tmp.insert(now);
now *= a[];
if (now > 25e16)
return m + sz_tmp - cnt;
}
return tmp.size();
} int64 all[];
for (int i = ; i < ; ++ i)
all[i] = inte_dev(a[i], an[i], bn[i]); set<int> tmp;
VI tt; tt.clear();
for (int i = ; i < ; ++ i)
for (int j = ; j < all[i]; ++ j)
if (!tmp.count(an[i][j])){
tmp.insert (an[i][j]);
tt.PB (an[i][j]);
} vector<int> v[];
for (int i = ; i < ; ++ i)
v[i].clear();
tmp_sz = tmp.size();
for (int i = ; i < ; ++ i)
for (int j = ; j < tmp_sz; ++ j)
v[i].PB (gao(a[i], tt[j])); set<VI > ans;
ans.erase(ans.begin(), ans.end());
VI now = v[];
for (int i = ; i < n; ++ i){
if (!ans.count(now)) ans.insert(now);
now = vadd(now, v[]);
}
now = v[];
for (int i = ; i < m; ++ i){
if (!ans.count(now)) ans.insert(now);
now = vadd(now, v[]);
}
return ans.size();
} // BEGIN CUT HERE
public:
//void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); }
void run_test(int Case) { if ((Case == -) || (Case == )) test_case_0();}
private:
template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '\"' << *iter << "\","; os << " }"; return os.str(); }
void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "\tExpected: \"" << Expected << '\"' << endl; cerr << "\tReceived: \"" << Received << '\"' << endl; } }
void test_case_0() { int Arg0 = ; int Arg1 = ; int Arg2 = ; int Arg3 = ; int Arg4 = ; int Arg5 = ; int Arg6 = ; verify_case(, Arg6, count(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5)); }
void test_case_1() { int Arg0 = ; int Arg1 = ; int Arg2 = ; int Arg3 = ; int Arg4 = ; int Arg5 = ; int Arg6 = ; verify_case(, Arg6, count(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5)); }
void test_case_2() { int Arg0 = ; int Arg1 = ; int Arg2 = ; int Arg3 = ; int Arg4 = ; int Arg5 = ; int Arg6 = ; verify_case(, Arg6, count(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5)); }
void test_case_3() { int Arg0 = ; int Arg1 = ; int Arg2 = ; int Arg3 = ; int Arg4 = ; int Arg5 = ; int Arg6 = ; verify_case(, Arg6, count(Arg0, Arg1, Arg2, Arg3, Arg4, Arg5)); } // END CUT HERE }; // BEGIN CUT HERE
int main()
{
// freopen( "a.out" , "w" , stdout );
GeometricProgressions ___test;
___test.run_test(-);
return ;
}
// END CUT HERE

SRM 500(2-1000pt)的更多相关文章

  1. topcoder srm 500 div1

    problem1 link 如果decisions的大小为0,那么每一轮都是$N$个人.答案为0. 否则,如果答案不为0,那么概率最大的一定是一开始票数最多的人.因为这个人每一轮都在可以留下来的人群中 ...

  2. TC250专场

    SRM 623 DIV2 1000pt 题意:给出一个最多50*50的矩阵,每个单元可能为'.'.'P'.'A','.'代表空地,你每次操作可以把一个P或者A拿到空地上,求一个最大的含有相同字符的矩形 ...

  3. SRM149 - SRM150(少SRM150-DIV1-LV3)

    SRM 149 DIV2 1000pt 题意: 对于n个人,第i人有pi的钱.将他们分成不超过四个组,每组统一交费x,对每个人,若他拥有的钱超过x则交费,否则不交费.问最多能使这些人交多少钱. 1&l ...

  4. Topcoder 好题推荐

    SRM SRM147 DIV1 1000pt DP SRM148 DIV1 1100pt 递归 SRM149 DIV1 1000pt math SRM150 DIV1 500pt DP SRM469 ...

  5. SRM 618 DIV1 500

    非常棒的组合问题,看了好一会,无想法.... 有很多做法,我发现不考虑顺序的最好理解,也最好写. 结果一定是两种形式 A....A   dp[n-1] A...A...A sgma(dp[j]*dp[ ...

  6. SRM 615 DIV1 500

    TC 都615了...时间过的真快啊. 第一次做出500分,心情还是很激动的,虽然看了很久的题解,TC官网上的题解,很详细,但是英语的...我搜了搜,发现一份日语的...好吧,我还是看看英语的吧... ...

  7. topcoder srm 628 div2 250 500

    做了一道题,对了,但是还是掉分了. 第二道题也做了,但是没有交上,不知道对错. 后来交上以后发现少判断了一个条件,改过之后就对了. 第一道题爆搜的,有点麻烦了,其实几行代码就行. 250贴代码: #i ...

  8. SRM 719 Div 1 250 500

    250: 题目大意: 在一个N行无限大的网格图里,每经过一个格子都要付出一定的代价.同一行的每个格子代价相同. 给出起点和终点,求从起点到终点的付出的最少代价. 思路: 最优方案肯定是从起点沿竖直方向 ...

  9. TopCoder SRM 639 Div.2 500 AliceGameEasy

    题意: 一个游戏有n轮,有A和B比赛,谁在第 i 轮得胜,就获得 i 分,给出x,y,问A得x分,B得y分有没有可能,如果有,输出A最少赢的盘数 解题思路: 首先判断n(n+1)/2 = (x+y)是 ...

随机推荐

  1. 学习java随笔第一篇:搭建java平台(java se)

    电脑系统:windows8 在这里介绍一下java平台的3个版本: Java SE--Java Standard Edition,Java的标准版,主要用于桌面级的应用和数据库开发. Java EE- ...

  2. ubuntu12.04安装QQ2013

    1.下载Longene QQ2013SP6 http://pan.baidu.com/s/1hq83fWo 2.安装 1)如果之前安装过旧版本需要先卸载(通过dpkg -l | grep qq查看). ...

  3. [转]Windows中的命令行提示符里的Start命令执行路径包含空格时的问题

    转自:http://www.x2009.net/articles/windows-command-line-prompt-start-path-space.html 当使用Windows 中的命令行提 ...

  4. 华硕_ZX50JX4200 安装ssd固态盘

    本人亲身的一次经历,帮朋友的华硕手提装一个内存和ssd固态 内存5分钟搞定,但是ssd固态盘就经过了一番的折腾 首先要拧掉所有后盖的螺丝,把光驱拆下来,注意撬开键盘板的时候有排线,不能弄断了.然后一定 ...

  5. slf4j与log4j

    推荐使用SLF4J(Simple Logging Facade for Java)作为日志的api,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统. ...

  6. ZOJ 刷题记录 小黑屋 (`・д・´)

    P1006:模拟 然而我的同余方程能过样例然而就是WA⊙﹏⊙b [已查明:扩展欧几里得算法出了很隐蔽的问题] int exGcd(int x,int y,int& a,int& b) ...

  7. list-style-type -- 定义列表样式

    取值:disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek ...

  8. dedecms自定义表单提交成功如何返回当前页面

    在plus/diy.php找到showmsg($bkmsg, $goto);改成showmsg($bkmsg, -1);

  9. ecshop--加载初始化文件

    define('IN_ECS', true);require(dirname(__FILE__) . '/../../includes/init.php'); 在开头要加入这两句文件才可以访问数据库以 ...

  10. apache 设置404页面

    这几天用xampp搭建了一套环境,后来发现在网页访问出现404的时候xampp显示的内容不安全,把apache.php还有一些其它的版本都会显示 出来,所以想自己设置一个404的页面,在网上找了一些资 ...