洛谷P3757 CQOI2017 老C的鍵盤

2022-02-28 01:43:31 字數 1077 閱讀 9229

傳送門

首先可以直接把整個序列建成乙個完全二叉樹的結構,這個應該都看得出來

然後考慮樹形dp,以大於為例

設$f[i][j]$表示$i$這個節點在子樹中排名第$j$位時的總方案數(因為實際只與相對大小有關,與實際數值無關)

我們考慮如果從當前子樹中弄出$k$個節點,其他子樹中弄出$j-1$個節點,那麼當前節點的大小排名就是$k+j$

然後考慮一下,如果我們不看這個子樹,根節點排在第$j$個,方案數是$f[i][j]$,如果只看此子樹,此子樹的根就是根節點的兒子,它在此子樹中的排名可能是$1,2,...k$,那麼我們就需要記錄一下字首和

然後考慮合併排列

對於小於根節點的,選出$j-1$個非此子樹,對於大於根節點的,選出$sum[x]-1$個非此子樹里弄出來的,那麼就是乙個組合問題了

1

//minamoto

2 #include3 #include4 #include5

#define ll long long

6using

namespace

std;

7const

int n=105,mod=1e9+7;8

int n,tot;char

s[n];

9ll f[n][n],g[n][n],tmp[n],c[n][n];

10int head[n],ver[n<<1],next[n<<1

],sum[n];

11 inline void add(int u,int

v)14

void dfs(int

x)30 sum[x]+=sum[v];

31for(int j=1;j<=sum[x];++j)

32 f[x][j]=tmp[j]%mod,g[x][j]=(g[x][j-1]+f[x][j])%mod;33}

34}35int

main()

44 dfs(1);printf("

%lld\n

",g[1][sum[1

]]);

45return0;

46 }

洛谷 P3757 CQOI2017 老C的鍵盤

luogu 其實就是一顆二叉樹 我們假設左兒子小於根,右兒子大於根 考慮樹形 dp f u i 表示以 u 為根的子樹,u 為第 i 小 那麼考慮子樹合併 其實就是兩個序列的合併 如果是左子樹 列舉 j 為子樹內有多少個數小於其根 那麼以 i 為根的子樹一定至少有 j 個 那麼我們換一下列舉的東西 ...

洛谷P4170 CQOI2007 塗色

假設你有一條長度為5的木版,初始時沒有塗過任何顏色。你希望把它的5個單位長度分別塗上紅 綠 藍 綠 紅色,用乙個長度為5的字串表示這個目標 rgbgr。每次你可以把一段連續的木版塗成乙個給定的顏色,後塗的顏色覆蓋先塗的顏色。例如第一次把木版塗成rrrrr,第二次塗成rgggr,第三次塗成rgbgr,...

洛谷 P4170 CQOI2007 塗色

假設你有一條長度為5的木版,初始時沒有塗過任何顏色。你希望把它的5個單位長度分別塗上紅 綠 藍 綠 紅色,用乙個長度為5的字串表示這個目標 rgbgr。每次你可以把一段連續的木版塗成乙個給定的顏色,後塗的顏色覆蓋先塗的顏色。例如第一次把木版塗成rrrrr,第二次塗成rgggr,第三次塗成rgbgr,...