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)是 ...
随机推荐
- DataTable和List集合互转
/// <summary> /// 将集合转换成DataTable /// </summary> /// <param name="list"> ...
- 虚拟机VHD格式解析到NTFS文件系统解析
本来的需求是XEN下的镜像取证,但这篇仅包括他支持的一种格式,就是VHD,此项目从头开始大概用了两周时间,中间遇到了很多让人头大的问题,光是思考的笔记就写了十几页纸,不过实际上并没有那么难,主要是很久 ...
- hibernate映射关系之多对多
多对多: * 关系在第三张表中,和两张表本身没有关系 * 多对多谁维护关系:谁都能维护关系(效率是一样的),一般情况下可以通过页面 来体现 * 关系体现: 第三张表的维护:增加.删除 course类对 ...
- ibatis集成Sqlite:小数据库也有大作用
作者:Vinkn 来自http://www.cnblogs.com/Vinkn/ 一.简介 Ibatis简介: Ibatis是一个类似于Hibernate的数据库ORM(对象关系映射,通俗点就是将数据 ...
- js登录页面的 回车事件
js登录页面的 回车事件 js登录页面的 回车事件(2012-12-26 10:37:03)转载▼标签: jseventkey回车事件登录 分类: js.jquery //回车事件 第一种docum ...
- 每个Linux新手都应该记住的10个基本Linux命令
Linux对我们的生活有着很大的影响.至少,你的安卓手机上面就有Linux内核.然而,头一次入手Linux只会让你觉得不适.因为在Linux上,你通常应该使用终端命令,而不是只要点击启动器图像(就像你 ...
- css杂项,清除浮动
在写HTML代码的时候,发现在Firefox等符合W3C标准的浏览器中,如果有一个DIV作为外部容器,内部的DIV如果设置了float样式,则外部的容器DIV因为内部没有clear,导致不能被撑开.看 ...
- Git error- fatal- Needed a single revision
最近在开发中由于项目结构的重构,有一部分代码被抽出来作为了公共库(git submodule),这样公共库可以独立维护,同时其他库调用它也是非常方便的,避免了到处复制代码的痛苦. 但我在项目重构后第一 ...
- iOS · 安装RVM cocoaPods 及问题解决
一.安装RVM 1.RVM:ruby版本管理器,命令行工具 管理Ruby 开始安装吧~ 对!!就是这样换成taobao ⬇️ $ gem sources -l $ gem sources --remo ...
- 最新iOS 6 in Xcode4.5新特性——Storyboard和属性自动绑定
最新iOS 6 in Xcode4.5新特性编程之二(上)——Storyboard和属性自动绑定 从Xcode 4.3开始,Storyboard 就是iOS 5和iOS 6中令人兴奋的一个新特性,他将 ...