給你一棵帶點權的樹,求將樹變成一堆不相交的鏈,而且這些鏈的權值和非負的方案數。
顯然這道題是個\(dp\)。
首先求個字首和\(sum\)。
為了後面講述方便,我這樣設:\(f_\)表示以\(i\)為根的子樹,其中某條鏈從\(x\)伸出到\(i\)的方案數,而且\(sum_x=j\)。
還有設\(g_i\)表示以\(i\)為根的,沒有伸出去的鏈的方案數。
顯然有這樣的轉移:
\[\prod g_i\to f_\\
f_\prod_ g_i\to f_x,j\]
\[f_ \to g_x \ (j-sum_\geq 0)\\
f_f_\prod_g_i\to g_x \ (j+k-2sum_x+a_x\geq 0)
\]如果直接這樣搞肯定會**。所以考慮用線段樹來維護\(f\)。
由於可能會出現\(g\)值為\(0\)的情況,所以不能直接用逆元來搞。
要維護個字首積和字尾積。
首先要求出重兒子,把重兒子作為第乙個兒子,然後線段樹合併之前也啟發式合併。
具體來說,我們欽定\(j。在合併的時候(設前面子樹合併出來的線段樹為\(a\),這個線段樹為\(b\))當前的兒子作為\(k\),遍歷\(b\)的所有葉子節點,並在\(a\)中區間詢問。這時候記得要乘上字尾積。將詢問出來的東西加在\(g_x\)中。
然後兩個合併在一起。記得在合併之前,整個\(a\)乘子樹的\(g_x\),整個\(b\)乘字首積
。搞完這個再合併。
最後你就會愉快地發現,所有子樹合併之後就是上面第二行式子。這樣只需要把第一行的加進去。第四行的式子已經計算完了,只需要再加上第乙個式子就可以了。
然而這不是題解的做法,作為乙個小蒟蒻,表示看不懂題解……
using namespace std;
#include #include #include #include #define n 100010
#define inf 1000000000
#define mo 1000000007
int n;
int a[n];
struct edge e[n*2];
int ne;
edge *last[n];
struct node *null;
struct node
inline void pushdown()
} inline void update()
} d[n*40];
int cnt;
node *rt[n];
inline node *newnode());}
void add(node *&t,int l,int r,int x,int c)
t->pushdown();
int mid=l+r>>1;
if (x<=mid)
add(t->l,l,mid,x,c);
else
add(t->r,mid+1,r,x,c);
t->update();
}int query(node *t,int l,int r,int st,int en)
node *merge(node *a,node *b)
int calc(node *t,int l,int r,node *rt,int bor)
int fa[n],sum[n],siz[n],hs[n];
int son[n],ns,pre[n],suc[n];
int g[n];
void dp(int x)
if (!hs[x])
son[ns=1]=hs[x];
pre[0]=1,pre[1]=g[hs[x]];
for (edge *ei=last[x];ei;ei=ei->las)
if (ei->to!=fa[x] && ei->to!=hs[x])
suc[ns+1]=1;
for (int i=ns;i>=1;--i)
suc[i]=(long long)suc[i+1]*g[son[i]]%mo;
rt[x]=rt[hs[x]];
for (int i=2;i<=ns;++i)
add(rt[x],-inf,inf,sum[x],pre[ns]);
g[x]+=query(rt[x],-inf,inf,sum[fa[x]],inf);
g[x]>=mo?g[x]-=mo:0;
}int main()
好多樹形dp都可以用線段樹合併來優化啊……
JZOJ4331 清華集訓模擬 樹
給你一棵帶點權的樹,求將樹變成一堆不相交的鏈,而且這些鏈的權值和非負的方案數。顯然這道題是個dpdp dp。首先求個字首和sum sumsu m。為了後面講述方便,我這樣設 fi,jf fi,j 表示以i ii為根的子樹,其中某條鏈從x xx伸出到i ii的方案數,而且sum x jsum x j ...
JZOJ 4330 清華集訓模擬 幾何題
這題的複雜度是o 106log 106 的fft 害怕.jpg 預處理cnt i j k 表示x,y,z的差為i,j,k的有多少對,首先,xi xj可以變成xi mx xj mx為最大xi 那麼每位都是非負數了,現在要做3維的多項式乘法,考慮用2mx進製儲存這三個數,壓在一起變乙個數,這樣就把3維變...
JZOJ4330 清華集訓模擬 幾何題
也懶得解釋題目大意了 正解居然是fft fftff t?不要看題目的那個式子這麼長,也不要在那個式子上下手。其實我們會發現,不同的 xi xj,yi y j,zi zj x i x j,y i y j,z i z j xi x j y i y j z i z j 並不多。如果我們求出每個三元組的出現...