51Nod 1383&1048 整數分解為2的冪
阿新 • • 發佈:2019-02-11
題目
任何正整數都能分解成2的冪,給定整數N,求N的此類劃分方法的數量。
V1:。要對答案模。
V2:。將整個答案輸出。
解題思路
考慮每一種劃分方法的序列是怎樣從一個空的序列變來的。
顯然,它是要麼,要麼集體乘。
因此很快樂地得出
當然,如果要與接軌,那麼要換一種思路。
考慮將轉換為二進位制,則。
因此,如果知道每個劃分為2的冪的和的方案數,那麼這題就很好做了。
對於某個 的一種劃分方案,如果不是隻有它本身一個數,一定可以把這些2的冪按照升序排序,然後分成兩段,每一段的和都是。
設表示做完了進位制下的前位,最大的數為的方案數。
設表示組成,最大的數為的方案數。
有人想到這樣的轉移方程:
但是這樣會算重。
為了避免這,所以強制讓後面的數字大於等於 。
所以將後面的數字都除以之後,可以得出這麼一個方程:
顯然先預處理。
然後套上高精度,再卡常,就可以通過此題了。
卡常很重要,就是拿個,確定一下
然而不知道為什麼,高精度壓8位WA了,壓9位就沒事?!
程式碼
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 100
#define M 150
#define mo 1000000000
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct note{
int w,a[M];
};note f[N][N],g[N][N],ans,n,c;
int i,j,k,l,ys,x,tot;
int xx;
char s[32];
double x1,x2,x3;
note operator + (const note &a,const note &b){
c.w=a.w>b.w?a.w:b.w;
memset(c.a,0,sizeof(c.a));
int i;
fo(i,1,c.w){
c.a[i]+=a.a[i]+b.a[i];
c.a[i+1]+=c.a[i]/mo;