JZOJ 5186. 【NOIP2017提高组模拟6.30】tty's home
生活随笔
收集整理的這篇文章主要介紹了
JZOJ 5186. 【NOIP2017提高组模拟6.30】tty's home
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
Input
Output
Sample Input
input 1:
5
1 1 1 1 1
1 2
2 3
3 4
4 5
input 2:
5
0 1 0 1 0
1 2
2 3
3 4
4 5
Sample Output
output 1:
15
output 2:
12
Data Constraint
Solution
正難則反,這題我們可以轉換一下思路。姑且稱 可能 符合條件的一種方案為 一個匹配 。
設 A= 不加限制的匹配數(總量), B= 不符合條件的匹配數(部分),則答案即為 A-B 。
那么我們如何求出 A 和 B 呢?可以用到 樹形DP 的方法。
設 Fi 表示以 i 為根的子樹所產生的匹配數。則有轉移方程式:Fi=Fi?Fj+Fj(j∈Soni)(逐一組合)
處理完上述式子后,再有:Fi=Fi+1? (單獨自己也是一種匹配)
最后可以求出 A :
A=∑i=1nFi求 B 也同理,不過當 j 為最值點時不轉移 i 、當 i 為最值點時 Fi 不 +1 。
最后 A、B 相減即可得出答案,總時間復雜度是 O(N) 。
Code
#include<cstdio> #include<cstring> using namespace std; const int N=100001,mo=998244353; int tot,mx=-2147483647; int first[N],next[N<<1],en[N<<1]; int a[N]; long long f[N],g[N]; long long ans; inline int read() {int X=0,w=1; char ch=0;while(ch<'0' || ch>'9') {if(ch=='-') w=-1;ch=getchar();}while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+ch-'0',ch=getchar();return X*w; } inline void insert(int x,int y) {next[++tot]=first[x];first[x]=tot;en[tot]=y; } inline void dfs1(int x,int y) {for(int i=first[x];i;i=next[i])if(en[i]!=y){dfs1(en[i],x);(f[x]+=f[x]*f[en[i]]%mo+f[en[i]])%=mo;}ans+=++f[x]; } inline void dfs2(int x,int y) {for(int i=first[x];i;i=next[i])if(en[i]!=y){dfs2(en[i],x);if(a[en[i]]<mx) (g[x]+=g[x]*g[en[i]]%mo+g[en[i]])%=mo;}if(a[x]<mx) (ans+=mo-++g[x])%=mo; } int main() {int n=read();for(int i=1;i<=n;i++)if((a[i]=read())>mx) mx=a[i];for(int i=1;i<n;i++){int x=read(),y=read();insert(x,y);insert(y,x);}dfs1(1,0),dfs2(1,0);printf("%lld",ans);return 0; }總結
以上是生活随笔為你收集整理的JZOJ 5186. 【NOIP2017提高组模拟6.30】tty's home的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 5185. 【NOIP2017
- 下一篇: JZOJ 5195. 【NOIP2017