4013 HNOI2015 實驗比較

2021-07-26 22:56:04 字數 4607 閱讀 5480

time limit: 5 sec  

memory limit: 512 mb

submit: 535  

solved: 268 [

submit][

status][

discuss]小d 

n 張,編號為1 到

n。實驗分若干輪進行,在每輪實驗中,小

d會被要求**某兩張隨機選取的,

然後小d 

需要根據他自己主觀上的判斷確定這兩張誰好誰壞,或者這兩張質量差不多。

用符號「

<

」、「>

」和「=

」表示x和y

(x、y

x 和y 是編號,則

x表示x

「質量優於」y,

x>y 表示x

「質量差於」y,

x=y表示x和

y「質量相同」;也就是說,這種上下文中,「

<

」、「>

」、「=

」分別是質量優於、質量差於、質量相同的意思;在其他上下文中,這三個符號分別是小於、大於、等於的含義。質量比較的推理規則(在x和

y1)x < y

等價於y > x。(2

)若x < y 

且y = z

,則x < z。(3

)若x < y

且x = z

,則z < y。(4

)x=y

等價於y=x。(5

)若x=y

且y=z

,則x=z

。實驗中,小

d 需要對一些對

(x, y)

,給出x < y 

或x = y 

或x > y 

的主觀判斷。小

d 在做完實驗後,

忽然對這個基於區域性比較的實驗的一些全域性性質產生了興趣。在主觀實驗資料給定的情形下,定義這

n 張的乙個合法質量序列為形如「

x1 r1 x2 r2 x3 r3 

…xn-1 rn-1 xn

」的串,也可看作是集合

,其中xi

為編號,

x1,x2,

…,xn

兩兩互不相同(即不存在重複編號),ri為

《或=,「合法」是指這個質量序列與任何一對主觀實驗給出的判斷不衝突。

例如:質量序列

3 < 1 = 2 

與主觀判斷「

3 > 1

,3 = 2」

衝突(因為質量序列中 3<1 

且1=2

,從而3<2

,這與主觀判斷中的

3=2 

衝突;同時質量序列中的

3<1 

與主觀判斷中的

3>1 

衝突),但與主觀判斷「

2 = 1

,3 < 2」

不衝突;因此給定主觀判斷「

3>1

,3=2」

時,1<3=2 

和1<2=3 

都是合法的質量序列,

3<1=2 

和1<2<3

都是非法的質量序列。由於實驗已經做完一段時間了,小

d 已經忘了一部分主觀實驗的資料。對每張i,小

d 都最多隻記住了某一張質量不比

i 差的另一張

ki。這些小

d 仍然記得的質量判斷一共有

m 條(

0 <= m <= n

),其中第

i 條涉及的對為

(kxi, xi)

,判斷要麼是

kxi   < xi  

,要麼是

kxi = xi

,而且所有的

xi互不相同。小

d 打算就以這

m 條自己還記得的質量判斷作為他的所有主觀資料。現在,基於這些主觀資料,我們希望你幫小

d 求出這

n 如果質量序列中出現「

x = y

」,那麼序列中交換x和

y的位置後仍是同乙個序列。

因此:1<2=3=4<5 

和1<4=2=3<5 

是同乙個序列,

1 < 2 = 3 

和1 < 3 = 2 

是同乙個序列,而

1 < 2 < 3 

與1 < 2 = 3

是不同的序列,

1<2<3

和2<1<3 

是不同的序列。

由於合法的質量序列可能很多,

所以你需要輸出答案對

10^9 + 7 

取模的結果

第一行兩個正整數n,m,分別代表總數和小d仍然記得的判斷的條數;

接下來m行,每行一條判斷,每條判斷形如」x < y」或者」x = y」。 

輸出僅一行,包含乙個正整數,表示合法質量序列的數目對 10^9+7取模的結果。

5 4

1 < 2

1 < 3

2 < 4

1 = 5

5不同的合法序列共5個,如下所示: 

1 = 5 < 2 < 3 < 4 

1 = 5 < 2 < 4 < 3 

1 = 5 < 2 < 3 = 4 

1 = 5 < 3 < 2 < 4 

1 = 5 < 2 = 3 < 4 

100%的資料滿足n<=100。  

[ submit][

status][

discuss]

注意到對於第i張**,不比i差的**最多只有一張

首先用並查集把所有等號合併,如果有關係i < j,那麼連一條有向邊(i,j)

如果無解,肯定會形成環,否則,對所有入度為0的點,連有向邊(0,i),這樣就將原圖構成了一棵樹

考慮樹上dp,定義f[i][j]:以i為根的子樹中,分成了j種等級,方案數

轉移的話,考慮逐個處理好兒子k的情況,將所有情況暴力列舉然後合併到i裡

這樣就變成,需求將乙個a種等級的序列和另乙個b種等級的序列合併成k種等級的序列的方案數

合併成k種等級等於有k個坑要填,同乙個序列中任意兩個數不能放在同乙個坑里

但是不同序列中的兩個數就沒有這樣的限制了

不妨先將序列a的數字放入坑中,共c[k][a]種填法

然後把b的也放進來,先要把空位填滿,然後和a中任意一些數字合併

所以方案共是c[k][a] * c[a][a + b - k]

複雜度的話,看似o(n^4),但是,每個點對只會在其lca處被列舉到並產生o(n)的運算量

精細地實現的話複雜度是o(n^3)的

#include#include#include#include#includeusing namespace std;

const int maxn = 111;

typedef long long ll;

const ll mo = 1000000007;

const char d[3] = ;

int n,m,fa[maxn],du[maxn],siz[maxn],f[maxn][maxn],h[maxn],c[maxn][maxn];

bool g[maxn][maxn],vis[maxn];

vector v[maxn],g[maxn];

queue q;

int mul(const ll &x,const ll &y)

int add(const int &x,const int &y)

int getfa(int k)

int read()

int getint()

void dfs(int x)

memcpy(f[x],h,sizeof(h)); memset(h,0,sizeof(h)); siz[x] += siz[y];

}} int main()

for (int i = 1; i <= n; i++) fa[i] = i;

while (m--)

}for (int i = 1; i <= n; i++)

}for (int i = 1; i <= n; i++)

if (!du[i] && fa[i] == i) ++du[i],v[0].push_back(i);

q.push(0);

while (!q.empty())

}for (int i = 1; i <= n; i++) if (!vis[i] && fa[i] == i)

dfs(0); int ans = 0;

for (int i = 1; i <= siz[0]; i++) ans = add(ans,f[0][i]);

cout << ans << endl;

return 0;

}

BZOJ4013 HNOI2015 實驗比較

先並查集合並 因為所有的xi互不相同,所以合併完後應該是乙個森林,如果出現環就無解。我們新建乙個根連向所有入度為0的點,就變成了一棵樹,考慮樹形dp。因為只要兩點不是其中一點是另一點的祖先的關係,他們就可以劃 因為大小關係不確定,所以將 連線的看做一塊,f i j 表示以 i 為根的子樹分成了j塊 ...

BZOJ 4013 HNOI2015 實驗比較

樹dp 組合數 網上題解很多,這裡就放個有注釋的 code 1 include 2 include 3 include 4 include 5 include 6 include 7 define maxn 110 8 define mod 1000000007 9using namespace s...

bzoj4013 HNOI2015 實驗比較

傳送門 思路 首先把等於的縮成乙個點,由好的向壞的連邊,有環肯定無解。然後題目裡說 小 d都最多隻記住了某一張質量不比 i差的另一張 ki 那就是每個點就最多只有一條入邊,那存在合法方案的圖就一定是森林。加乙個虛根,這可以樹形dp了。假設f i j 表示i號點的子樹中的所有點構成的有且只有j個小於號...