JSOI2016 無界單詞

2022-09-01 04:45:11 字數 1242 閱讀 6282

題目描述

對於乙個單詞 $s$ ,如果存在乙個長度 $l$,滿足 $0\lt l\lt |s|$,並且使得 $s$ 長度為 $l$ 的字首與 $s$ 長度為 $l$ 的字尾相同,jyy 則稱 $s$ 是有界的。比如 `aabaa` 和 `ababab` 就都是有界的字串。如果乙個單詞不存在這樣的 $l$ ,則 jyy 稱之為無界單詞。

現在考慮所有僅由字母 `a` 和 `b` 組成的長度為 $n$ 的字串,jyy想知道:

1. 一共有多少個無界單詞?

2. 這些無界單詞中,按字典序排列第 $k$ 小的單詞是哪乙個?

資料範圍

對於全部資料,滿足 $1\le t\le 5,1\le n\le 64$ ,並且保證對於任意測試資料,總存在第 $k$ 小的無界單詞。

題解

考慮到每個有界單詞總是能表示成兩個無界單詞放在首位且長度不超過該有界單詞的一半。

於是可以考慮 $dp$ , $f_i$ 表示長度為 $i$ 的無界單詞的個數,轉移考慮容斥即可。

第二問只需要按位考慮即可,將 $dp$ 狀態表示成長度為 $i$ ,且前 $len$ 為已經確定的無界單詞的個數,轉移是類似的。

**

#include using

namespace

std;

#define u unsigned long long

const

int n=70

;const u b=793999

;int

t,n,a[n];

u k,f[n],b[n],g[n];

u h(

int l,int

r)bool j(int

x)void

work()

if (n==64) f[n]--;

cout

for (int h=1;h<=n;h++)

else f[i]+=f[j]*((u)1

<<(i-j-max(j,h)));

}f[i]=((u)1

<<(i-h))-f[i];

}if (f[n]f[n];

putchar(a[h]+97

); g[h]=g[h-1]*b+a[h]+1

; }

putchar('\n

');}int

main()

JSOI2016 無界單詞

題目 題意 求 rm border 長度為 0 的 n 位 0,1 字串個數,並求字典序第 k 小的那乙個。首先是計數,正向不是很好算,考慮正難則反 設 f i 表示長度為 i 的 rm border 0 的串的個數 乙個串可能有多個 rm border 我們考慮在其最小的 rm border 長度...

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...