題目
題意:求\(\rm border\)長度為\(0\)的\(n\)位\(0,1\)字串個數,並求字典序第\(k\)小的那乙個。
首先是計數,正向不是很好算,考慮正難則反;設\(f_i\)表示長度為\(i\)的\(\rm |border|=0\)的串的個數
乙個串可能有多個\(\rm border\),我們考慮在其最小的\(\rm border\)長度\(j\)時計算它
則有\(f_i=2^i-\sum_^\rfloor}f_j2^\);不用考慮長度大於\(\lfloor \frac\rfloor\)的\(\rm border\)是因為當\(\rm border\)長度大於\(\lfloor \frac\rfloor\)的時候一定存在乙個小於\(\lfloor \frac\rfloor\)的\(\rm border\)。
第二問,考慮大力二分;二分乙個串,求所有字典序小於等於這個串中,\(\rm border=0\)的有多少個
設\(g_\)表示長度為\(i\)且字典序嚴格小於當前串的前\(i\)位的串的個數;\(g_\)表示長度為\(i\)且等於當前串的前\(i\)位的串的個數;不難發現\(g_=[i\notin \rm border]\)
還是跑上面那個容斥,從\(g_\)向\(g_\)轉移的時候要在套乙個二分判斷一下
**,其中有一些詭異的行為都是為了防爆unsigned long long
#include#define re register
#define ll unsigned long long
int n,t;ll m,f[66],v[66];
ll g[2][66];int nxt[66],a[66];
inline void split(ll nw)
inline ll calc(ll val,ll r,int i,int j,ll h)
std::cout<>1ull)+(r>>1ull);
if((l&1ull)&&(r&1ull)) mid++;
if(calc(mid)>=m)
else l=mid+1;
} split(ans);
for(re int i=1;i<=n;i++)putchar(a[i]+'a');puts("");
}}
JSOI2016 無界單詞
題目描述 對於乙個單詞 s 如果存在乙個長度 l 滿足 0 lt l lt s 並且使得 s 長度為 l 的字首與 s 長度為 l 的字尾相同,jyy 則稱 s 是有界的。比如 aabaa 和 ababab 就都是有界的字串。如果乙個單詞不存在這樣的 l 則 jyy 稱之為無界單詞。現在考慮所有僅由...
JSOI2016 最佳團隊
這種最大化形如 x y 的式子的題,很容易想到分數規劃。二分答案,對於當前的mid,設d i p i mid s i 考慮到當乙個節點i被選,那麼fa i 也要被選,那麼乙個想法是選取當前最大的d,然後把它的兒子的d放入堆裡。但是這個方法是錯誤的 然而我一開始就這麼打了,只有10分 題目給出的是一棵...
JSOI2016 最佳團隊
看到這個什麼比值最大,立馬想到了二分答案。然後就變成了乙個樹上揹包問題,直接暴力合併揹包即可。暴力合併不是o n3 的嗎?記錄一下子樹的大小,揹包時的上界設為這個,就降成o n2 感性證明 你可以想象兩個點只會在它們的lca處合併。code include include define fd i,x...