bzoj千题计划164:bzoj5123: 线段树的匹配
2017-12-30 09:46
309 查看
http://www.lydsy.com/JudgeOnline/upload/201712/prob12.pdf
dp[len][0/1] 表示节点表示区间长度为len,节点选/不选的 最大匹配
sum[len][0/1] 表示对应dp[len][0/1]的方案数
这里选节点即选节点与其父节点的边
设区间长度为len,左子区间长度为L,右子区间长度为R
这个节点选,那么左右子节点都不能选
dp[len][1]=1+dp[L][0]+dp[R][0]
sum[len][1]=sum[L][0]*sum[R][0]
这个节点不选,有3种情况:
左右子节点都不选:
dp[len][0]=dp[L][0]+dp[R][0]
sum[len][0]=sum[L][0]+sum[R][0]
选左子节点:
dp[len][0]=dp[L][1]+dp[R][0]
sum[len][0]=sum[L][1]+sum[R][0]
选右子节点:
dp[len][0]=dp[L][0]+dp[R][1]
sum[len][0]=sum[L][0]+sum[R][1]
如果dp[len][0] 在三种情况中有相同的,sum[len][0]要累加
len虽然是1e18,但只会用log种,所以用map
dp[len][0/1] 表示节点表示区间长度为len,节点选/不选的 最大匹配
sum[len][0/1] 表示对应dp[len][0/1]的方案数
这里选节点即选节点与其父节点的边
设区间长度为len,左子区间长度为L,右子区间长度为R
这个节点选,那么左右子节点都不能选
dp[len][1]=1+dp[L][0]+dp[R][0]
sum[len][1]=sum[L][0]*sum[R][0]
这个节点不选,有3种情况:
左右子节点都不选:
dp[len][0]=dp[L][0]+dp[R][0]
sum[len][0]=sum[L][0]+sum[R][0]
选左子节点:
dp[len][0]=dp[L][1]+dp[R][0]
sum[len][0]=sum[L][1]+sum[R][0]
选右子节点:
dp[len][0]=dp[L][0]+dp[R][1]
sum[len][0]=sum[L][0]+sum[R][1]
如果dp[len][0] 在三种情况中有相同的,sum[len][0]要累加
len虽然是1e18,但只会用log种,所以用map
#include<map> #include<cstdio> #include<cstring> using namespace std; typedef long long LL; const int mod=998244353; //int dp[100001][2]; //int sum[10001][2]; map<LL,LL>dp[2]; map<LL,LL>sum[2]; void dfs(LL len) { if(len==1) { dp[0][1]=0; sum[0][1]=1; dp[1][1]=1; sum[1][1]=1; return; } LL R=len>>1; LL L=len-R; if(dp[0].find(L)==dp[0].end()) dfs(L); if(dp[0].find(R)==dp[0].end()) dfs(R); dp[1][len]=1+dp[0][L]+dp[0][R]; sum[1][len]=sum[0][L]*sum[0][R]%mod; dp[0][len]=dp[1][len]-1; sum[0][len]=sum[1][len]; if(dp[0][L]+dp[1][R]>dp[0][len]) { dp[0][len]=dp[0][L]+dp[1][R]; sum[0][len]=sum[0][L]*sum[1][R]%mod; } else if(dp[0][L]+dp[1][R]==dp[0][len]) { sum[0][len]=(sum[0][len]+sum[0][L]*sum[1][R])%mod; } if(dp[1][L]+dp[0][R]>dp[0][len]) { dp[0][len]=dp[1][L]+dp[0][R]; sum[0][len]=sum[1][L]*sum[0][R]%mod; } else if(dp[1][L]+dp[0][R]==dp[0][len]) { sum[0][len]=(sum[0][len]+sum[1][L]*sum[0][R])%mod; } } int main() { LL n; scanf("%I64d",&n); dfs(n); printf("%I64d %I64d",dp[0] ,sum[0] ); }
相关文章推荐
- BZOJ 5123([Lydsy12月赛]线段树的匹配-记忆化搜索)
- bzoj5123 [Lydsy12月赛]线段树的匹配
- 【bzoj5123】[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索
- bzoj 1758: [Wc2010]重建计划 长链剖分+线段树
- BZOJ 3333 排队计划 树状数组+线段树
- BZOJ 3207 花神的嘲讽计划Ⅰ Hash+可持久化线段树
- [三合一 BFS 平衡树 线段树] BZOJ 2158 Crash 的旅行计划
- [树状数组 线段树] BZOJ 3333 排队计划
- BZOJ-3207 花神的嘲讽计划Ⅰ ,hash+可持久化线段树
- [BZOJ 3207] 花神的嘲讽计划Ⅰ【Hash + 可持久化线段树】
- 【BZOJ】【P3578】【GTY的人类基因组计划2】【题解】【线段树套set or 线段树+set+hash】
- 【BZOJ3291】Alice与能源计划 二分图最大匹配
- BZOJ 3207 花神的嘲讽计划Ⅰ(函数式线段树)
- BZOJ 3207: 花神的嘲讽计划Ⅰ( hash + 可持久化线段树 )
- [长链剖分 & 线段树] BZOJ1758[Wc2010] 重建计划
- BZOJ 3333: 排队计划 树状数组 线段树
- [BZOJ2034]&[BZOJ4276]-最大收益-线段树优化建边/贪心优化最大权匹配
- BZOJ 3207 花神的嘲讽计划Ⅰ 可持久化线段树
- bzoj 2733: [HNOI2012]永无乡 (线段树合并)[省选计划系列]
- 【BZOJ 3207】花神的嘲讽计划Ⅰ(Hash + 可持久化线段树)