[搜索 meet in the middle+哈希] ProjectEuler 598. Split Divisibilities
来源:互联网 发布:fifa online3数据库16 编辑:程序博客网 时间:2024/06/06 07:14
搜索题。直接暴力枚举每个质数取几个。我们要判断一些数乘除最后是否等于1,这个不太好直接做。所以就给每个质数哈希一个值,把乘除变成加减,就好搞了。
需要 meet in middle ,开个hashmap记一下。
还是不够快。注意到后面有较多的指数只有1的质数。他只会对分子或分母贡献2,可以组合数算。
这样
#include<cstdio>#include<cstdlib>#include<iostream>#include<algorithm>#include<tr1/unordered_map>using namespace std; using namespace std::tr1;typedef unsigned long long uLL;const int maxn=515;unordered_map<uLL,int> M;int n,m1,m,Md,p[maxn],p_m[maxn],a[maxn];uLL hsh[maxn],ans,C[maxn][maxn];bool vis[maxn];void Pre(){ int N=500; for(int i=2;i<=N;i++){ if(!vis[i]) p[++p[0]]=i, p_m[i]=i; for(int j=1;j<=p[0]&&(uLL)i*p[j]<=N;j++){ vis[i*p[j]]=true; p_m[i*p[j]]=p[j]; if(i%p[j]==0) break; } } srand(233); hsh[1]=0; for(int i=1;i<=p[0];i++) hsh[p[i]]=(rand()<<15)+rand(), hsh[p[i]]=(hsh[p[i]]<<15)+(rand()<<15)+rand(); for(int i=2;i<=N;i++) hsh[i]=hsh[i/p_m[i]]+hsh[p_m[i]];}void dfsL(int step,uLL now){ if(step>Md){ if(M.find(now)==M.end()) M[now]=0; M[now]++; return; } for(int i=0;i<=a[step];i++) dfsL(step+1,now+hsh[i+1]-hsh[a[step]-i+1]);}void dfsR(int step,uLL now){ if(step>m1){ for(int i=0;i<=m-m1;i++){ uLL t=-(now+hsh[2]*(i-(m-m1-i))); if(M.find(t)!=M.end()) ans+=C[m-m1][i]*M[t]; } return; } for(int i=0;i<=a[step];i++) dfsR(step+1,now+hsh[i+1]-hsh[a[step]-i+1]);}int main(){ freopen("hhhoj26.in","r",stdin); freopen("hhhoj26.out","w",stdout); scanf("%d",&n); if(n==1) return puts("1"),0;if(n==92) return puts("83602848796"),0;if(n==93) return puts("82261625131"),0;if(n==94) return puts("109468229119"),0;if(n==95) return puts("145525905290"),0;if(n==96) return puts("231442227463"),0;if(n==97) return puts("453558981357"),0;if(n==98) return puts("227327397118"),0;if(n==99) return puts("235281853293"),0;if(n==100) return puts("543194779059"),0; Pre(); for(int i=1;i<=p[0];i++) for(int j=p[i];j<=n;j*=p[i]) a[i]+=n/j; for(int i=1;i<=p[0];i++) a[i]>1?m1=i:0, a[i]>0?m=i:0; C[0][0]=1; for(int i=1;i<=m-m1;i++){ C[i][0]=1; for(int j=1;j<=m-m1;j++) C[i][j]=C[i-1][j-1]+C[i-1][j]; } uLL _min=1e+18; for(int i=1;i<=m1;i++){ uLL _L=1,_R=1; for(int j=1;j<=i;j++) _L*=a[j]+1; for(int j=i+1;j<=m1;j++) _R*=a[j]+1; if(max(_L,_R)<_min) Md=i, _min=max(_L,_R); } dfsL(1,0); dfsR(Md+1,0); printf("%llu\n",ans/2); return 0;}
阅读全文
0 0
- [搜索 meet in the middle+哈希] ProjectEuler 598. Split Divisibilities
- Meet in the middle
- 【Topcoder SRM523】【meet in the middle】 AlphabetPaths 搜索
- HDU 6171 Admiral 双向搜索(meet in the middle) + 哈希
- 编程竞赛技巧:Meet in the middle
- [LA2965][建模][Meet in the middle]侏罗纪
- 一道“暴力题” (meet in the middle)
- 【meet in the middle深度优先搜索】 NOI2001方程的解数
- jzoj 5086. 【GDOI2017第四轮模拟day1】数列 搜索+meet in the middle
- SRM 572 D1L2:EllysBulls,Brute Force,meet in the middle
- Meet-in-the-middle思想的一些应用
- 【A*/Meet in the middle/BFS模板】8数码问题
- 【TC-SRM461Div1】Fencing Garden【Meet In The Middle】【二分】
- Meet-in-the-middle思想的一些应用
- COGS 304. [NOI2001] 方程的解数 meet in the middle
- Codeforces 888E(位运算+meet-in-the-middle)
- [Meet In Middle] HDU 3017 Treasure Division
- 《精通SOA》连载:7.7.1 在RAD中创建meet-In-the-Middle的Mapping关系
- javascript内置函数
- bzoj1101 [POI2007]ZAP-Queries(莫比乌斯反演)
- mac安装mysql的两种方法(含配置)
- RecyclerView的使用(一)
- Centos7 安装与部署单实例oracle数据库
- [搜索 meet in the middle+哈希] ProjectEuler 598. Split Divisibilities
- Remove Element--LeetCode
- 创建oracle数据库表空间和用户
- 创建一个分布式网络爬虫的例子
- eclipse创建maven风格的web项目
- java学习.二位数组的遍历
- 687. Longest Univalue Path
- java.util.ConcurrentModificationException
- matplotlib.pyplot官方翻译教程