乙個數列,其中a[0]=0,a[1]=1,a[2*i]=a[i],a[2*i+1]=a[i]+a[i+1],給出t個n,求a[n]。
然後我們需要推出通用的處理方法來利用p和q,不難想到x要分奇偶討論:
1.x為奇數
我們假設已經求好了下面的p和q,現在要把p和q對應到x-1和x上來,不難發現p不變,而q=p+q。
2.x為偶數
同理,不難發現q不變,而p=p+q。
所以對於乙個x,進行dfs((x+1)/2)(ps:(x+1)/2就不用判斷奇偶性了),得到下一層的p和q(遞迴到x=1為止),根據上述方法求得新p和q,最後根據定義,q就是a[x]。
時間複雜度:o(t*log2(n)*高精度)
最後,關於記憶化:通過上方討論就可以發現每隔1,2層就會出現重複,所以使用記憶化就可以把許多二叉做成一叉,效率近似log2(n)但有差距,不過實際表現非常不錯(特別是多組資料可能會減少許多組),也是一種可行的策略。
#include
#include
#include
using
namespace
std;
const
int maxl=25,tt=10000; //壓4位
int te;
char s[maxl*4+5];
struct bignum //高精度結構體
int& operator (int i)
void
operator = (int x) while (x);} //過載和int類的=
bignum(int x)
void
operator = (const
char *s) //過載和char類的=
}bignum(const
char *s)
void print()
};bignum n,p,q,c,bn_one=1;
bool eoln(char ch)
int reads(char *s) //讀入字元陣列
void readln()
bignum operator + (bignum a,bignum b) //過載+
while (c[c[0]+1]) c[0]++;while (c[0]>1&&!c[c[0]]) c[0]--;
return c;
}bignum operator / (bignum a,int x) //過載/
void dfs(bignum x) //dfs求a[x]
//特判0
if (x[0]==1&&x[1]==1) //邊界條件
dfs((x+bn_one)/2); //先求出之前的p和q
if (x[1]&1) q=p+q; else p=p+q; //根據奇偶性求新的p和q
}int main()
return
0;}
ZJOI2018 Day1 簡要題解
乙個結論是,lk t lk t 的每個節點在原樹上是乙個不超過 k 1 k 1 個點的連通塊。考慮用括號序列列舉所有不同的有根樹,利用樹雜湊來去重,這樣的樹大概 1000 1000 個,然後答案就是它的貢獻乘上它在原樹上的出現次數。在原樹上的出現次數可以直接狀壓dp,可以加乙個剪枝,就是葉子單獨提出...
Day1 兩數之和
題目 給定乙個整數陣列 nums 和乙個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。你可以假設每種輸入只會對應乙個答案。但是,你不能重複利用這個陣列中同樣的元素。示例 給定 nums 2,7,11,15 target 9 因為 nums 0 nums 1...
ZJOI2018外省選手醬油記Day1
上午考試。又爆零了 下午講完題後放假 然後就滾回去收拾行李準備去zj z j衢州?我怎麼從來沒聽過這個地方。肯定是我見識少 上高鐵出發,3個 小時3 個小 時,看了一下電影,頹了一會兒紅警,聊了聊qq q q,然後就到了 一下車發現一堆hn h n選手來參賽,怎麼也有 50 50 個以上吧 直接跑去...