Gym 100801D Distribution in Metagonia(构造)
题意:
给你一个LL的数,让你把它分解为许多个数相加的形式,
要求这些数的质因子只有2和3并且这些数的因子2的个数和因子3的个数不能同时小于等于其他任意一个数
要求这些数的数量不超过100个
思路:
递归构造,如果当前数正好符合条件就终止,否则先让他把2和3尽可能的除去,并乘在tmp中作为公因子,
然后提取出小于他的最大的3的次方数,保证这个数的3的因子数最大,对于剩下的这个数再进行dfs递归直到刚好符合条件跳出
这样保证所有的数是按3的次方递减的,符合条件
/* *********************************************** Author :devil ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <stack> #include <map> #include <string> #include <time.h> #include <cmath> #include <stdlib.h> #define LL long long #define rep(i,a,b) for(int i=a;i<=b;i++) #define dep(i,a,b) for(int i=a;i>=b;i--) #define ou(a) printf("%d\n",a) #define pb push_back #define mkp make_pair template<class T>inline void rd(T &x) { char c=getchar(); x=0; while(!isdigit(c))c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } #define IN freopen("in.txt","r",stdin); #define OUT freopen("out.txt","w",stdout); using namespace std; const int inf=0x3f3f3f3f; const int mod=1e9+7; const int N=1e2+10; LL ans[N],f[42],n; int t,cnt; void dfs(LL tmp,LL u) { while(u%2==0){u/=2;tmp*=2;} while(u%3==0){u/=3;tmp*=3;} if(u==1){ans[cnt++]=tmp;return;} int p=upper_bound(f,f+40,u)-f-1; ans[cnt++]=f[p]*tmp; dfs(tmp,u-f[p]); } int main() { #ifndef ONLINE_JUDGE //IN #endif freopen("distribution.in","r",stdin); freopen("distribution.out","w",stdout); f[0]=1; for(int i=1;i<=39;i++) f[i]=f[i-1]*3; scanf("%d",&t); while(t--) { scanf("%lld",&n); cnt=0; dfs(1,n); printf("%d\n",cnt); for(int i=0;i<cnt;i++) printf("%lld%c",ans[i],i==cnt-1?'\n':' '); } return 0; }