lightoj1341Aladdin and the Flying Carpet(分解质因数+dfs)
2016-05-03 01:06
459 查看
题目链接:(http://lightoj.com/volume_showproblem.php?problem=1341)
题意大概就是给你一个长方形面积a,求满足长和宽都不少于b的情况数,长不等于宽,t(sqrt(a)-b)会爆,但是数据比较水没卡tsqrt(b),当然我是分解质因数然后暴力找约数xjb剪剪枝过的
顺带一提,tsqrt(b)的做法是分解质因数然后搞一搞就能得到约数的个数,然后暴力找不满足的,虽然复杂度有问题但是数据比较水还是能过的
题意大概就是给你一个长方形面积a,求满足长和宽都不少于b的情况数,长不等于宽,t(sqrt(a)-b)会爆,但是数据比较水没卡tsqrt(b),当然我是分解质因数然后暴力找约数xjb剪剪枝过的
#include <stdio.h> #include<cmath> #include<iostream> #include<cstring> using namespace std; typedef long long LL; bool is[1000010]; LL pri[100000]; LL cnt[100]; int nm[100]; LL b; int siz=0,siz1=0; int ans; void isprime(){ memset(is,0,sizeof(is)); memset(pri,0,sizeof(pri)); for(LL i=2;i<=1000000;i++){ if(!is[i])pri[++siz]=i; for(int j=1;j<=siz&&i*pri[j]<=1000000;j++){ is[i*pri[j]]=1; if(!(i%pri[j]))break; } } } void gao(LL a){ LL mx=sqrt(a); memset(cnt,0,sizeof(cnt)); memset(nm,0,sizeof(nm)); cnt[1]=1; nm[1]=0; siz1=1; for(int i=1;i<=siz;i++){ while((a%pri[i])==0){ if(cnt[siz1]!=pri[i])cnt[++siz1]=pri[i]; nm[siz1]++; a/=pri[i]; } if(pri[i]>mx||pri[i]>a)break; } } void dfs(int pp,LL nw,LL mx){ if(nw>mx)return ; if(pp>siz1){ if(nw>=b)ans++; return ; } for(int i=0;i<=nm[pp];i++){ dfs(pp+1,nw,mx); nw*=cnt[pp]; } } int main(void) { LL a; isprime(); int t,cas=0; scanf("%d",&t); while(t--){ scanf("%lld%lld",&a,&b); gao(a); ans=0; LL mx=sqrt(a); if(mx*mx==a)mx--; dfs(1,1,mx); printf("Case %d: %d\n",++cas,ans); } return 0; }
顺带一提,tsqrt(b)的做法是分解质因数然后搞一搞就能得到约数的个数,然后暴力找不满足的,虽然复杂度有问题但是数据比较水还是能过的