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個小於號...