SRM 500(2-1000pt)
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)的更多相关文章
- topcoder srm 500 div1
problem1 link 如果decisions的大小为0,那么每一轮都是$N$个人.答案为0. 否则,如果答案不为0,那么概率最大的一定是一开始票数最多的人.因为这个人每一轮都在可以留下来的人群中 ...
- TC250专场
SRM 623 DIV2 1000pt 题意:给出一个最多50*50的矩阵,每个单元可能为'.'.'P'.'A','.'代表空地,你每次操作可以把一个P或者A拿到空地上,求一个最大的含有相同字符的矩形 ...
- SRM149 - SRM150(少SRM150-DIV1-LV3)
SRM 149 DIV2 1000pt 题意: 对于n个人,第i人有pi的钱.将他们分成不超过四个组,每组统一交费x,对每个人,若他拥有的钱超过x则交费,否则不交费.问最多能使这些人交多少钱. 1&l ...
- Topcoder 好题推荐
SRM SRM147 DIV1 1000pt DP SRM148 DIV1 1100pt 递归 SRM149 DIV1 1000pt math SRM150 DIV1 500pt DP SRM469 ...
- SRM 618 DIV1 500
非常棒的组合问题,看了好一会,无想法.... 有很多做法,我发现不考虑顺序的最好理解,也最好写. 结果一定是两种形式 A....A dp[n-1] A...A...A sgma(dp[j]*dp[ ...
- SRM 615 DIV1 500
TC 都615了...时间过的真快啊. 第一次做出500分,心情还是很激动的,虽然看了很久的题解,TC官网上的题解,很详细,但是英语的...我搜了搜,发现一份日语的...好吧,我还是看看英语的吧... ...
- topcoder srm 628 div2 250 500
做了一道题,对了,但是还是掉分了. 第二道题也做了,但是没有交上,不知道对错. 后来交上以后发现少判断了一个条件,改过之后就对了. 第一道题爆搜的,有点麻烦了,其实几行代码就行. 250贴代码: #i ...
- SRM 719 Div 1 250 500
250: 题目大意: 在一个N行无限大的网格图里,每经过一个格子都要付出一定的代价.同一行的每个格子代价相同. 给出起点和终点,求从起点到终点的付出的最少代价. 思路: 最优方案肯定是从起点沿竖直方向 ...
- 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)是 ...
随机推荐
- Android平台的四大天王:Activity, Service, ContentProvider, BroadcastReceiver
今天开始要自学android,刚看到百度知道上面这段话,觉得不错(不过已经是2011年8月的回答了): Android系统的手机的每一个你能看到的画面都是一个activity,它像是一个画布,随你在上 ...
- [总结]FFMPEG视音频编解码零基础学习方法
在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的初学者.在和大家探讨的过程中,我忽然发现了一个问题:在“ ...
- Missing iOS Distribution signing identity问题解决
问题描述 打包上传APPStore Xcode报以下错误:Missing iOS Distribution signing identity for XXXXXX 查看证书后发现,Develop证书 ...
- ROW_NUMBER() OVER函数的基本用法用法
ROW_NUMBER() OVER函数的基本用法用法 转自:http://www.cnblogs.com/icebutterfly/archive/2009/08/05/1539657.html 语法 ...
- impress.js学习总结
impress.js是一个很有趣的用来替代PPT的展示用的js工具,它的灵感来自prezi 如果你要学习使用它,这里有很好的演示模板 使用它的第一步,下载 impress.js,引入到你的代码里,并执 ...
- 微博输入相关js 代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 在MAC下 Python+Django+mysql配置
今天在搭建Django+mysql环境的时候遇到了一点问题,记录下来. 安装环境:OS X 10.10操作系统,Python 2.7. MySQLdb其实包含在MySQL-python包中,因此无论下 ...
- Markdown 测试
量化派业务参考代码 测试二级标题 如果 merchant_id 是外部白条,则执行相关逻辑 if(order.getMerchantId() == Constants.BaitiaoMerchant. ...
- 支付宝集成获取私钥与公钥-b
项目需要,需要在客户端集成支付宝接口.就研究了一下:因为使用支付宝接口,就需要到支付宝官网:注册帐号,并申请.下面讲的是申请好之后的操作.登录成功之后, 店家我的商家服务—在页面的下方找到——&g ...
- 转:PHP开发者应了解的24个库
原文来自于:http://blog.jobbole.com/54201/ 作为一个PHP开发者,现在是一个令人激动的时刻.每天有许许多多有用的库分发出来,在Github上很容易发现和使用这些库.下面是 ...