博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[CTSC2018]青蕈领主
阅读量:6599 次
发布时间:2019-06-24

本文共 2476 字,大约阅读时间需要 8 分钟。

 

首先,连续段要知道结论:

连续段要么不交,要么包含

所以是一棵树!每个位置的father是后面第一个包含它的

树形DP!

设dp[x],x为根的子树,(设管辖的区间长度为len,也即L[x]),用1~len的数填充,满足L的方案数

也就是,每个son内部合法,

给每个son分配标号区间,使得相邻儿子不会再接在一起

不会再接在一起?

 所以可以把每个儿子看成单独一个点,就划归成了:1,1,1,1,...len的方案数!

 

设f[i]表示,长度为i+1的1,1,1,1....i+1的序列的合法方案数。

$dp[x]=(\Pi dp[son])\times f[L[x]]$

归纳一下,可得$ans=\Pi f[|son(x)|]$,$|son(x)|$表示x的儿子个数

 

求f[n]?

考虑变成排列的逆!

(也就是把映射矩阵的横纵坐标意义交换)

这样,n+1成为了天然的分割点。

 

f[n-1]中,填入1,

要么之前合法。

要么1分开了一些东西

|son(x)|可以直接单调栈

 

注意,Poly每次clear需要重新resize

 

#include
#define reg register int#define il inline#define fi first#define se second#define mk(a,b) make_pair(a,b)#define numb (ch^'0')#define pb push_back#define solid const auto &#define enter cout<
using namespace std;typedef long long ll;template
il void rd(T &x){ char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}template
il void output(T x){
if(x/10)output(x/10);putchar(x%10+'0');}template
il void ot(T x){
if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}template
il void prt(T a[],int st,int nd){ for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}namespace Modulo{const int mod=998244353;int ad(int x,int y){ return (x+y)>=mod?x+y-mod:x+y;}void inc(int &x,int y){x=ad(x,y);}int sub(int x,int y){ return ad(x,mod-y);}int mul(int x,int y){ return (ll)x*y%mod;}void inc2(int &x,int y){x=mul(x,y);}int qm(int x,int y=mod-2){ int ret=1;while(y){ if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}template
il int ad(const int a,const int b,const Args &...args) { return ad(ad(a,b),args...);}template
il int mul(const int a,const int b,const Args &...args) { return mul(mul(a,b),args...);}} using namespace Modulo;namespace Miracle{const int N=50000+5;const int G=3;const int GI=332748118;int n,T;int L[N];struct Poly{ vector
f; Poly(){f.clear();} il int &operator[](const int &x){assert(x
>1]>>1)|((i&1)?m>>1:0); } return m;}void NTT(Poly &f,int c){ int n=f.size(); for(reg i=0;i
>1; divi(l,mid); // cout<<" divi ---------------------------"<
<<" "<
<
=i-L[i]+1) ++son,--top; // cout<<" ii "<
<<" son "<
<
=i-L[i]+1) fl=false; } sta[++top]=i; ans=mul(ans,f[son]); } if(!fl) ans=0; printf("%d\n",ans); } return 0;}}signed main(){ Miracle::main(); return 0;}/* Author: *Miracle**/

树形结构!

然后递归为子问题。

递归为子问题,把。。。看成。。。。

本质就是“缩点”找相似结构。或者归纳

 

转载于:https://www.cnblogs.com/Miracevin/p/11019351.html

你可能感兴趣的文章
Linux监控平台搭建(三)--自定义监控项目、问题告警及处理
查看>>
合拍在线:安全永远是互金行业发展的生命线
查看>>
TCP协议如何保证传输的可靠性
查看>>
Spring Cloud + Spring Boot + Mybatis + shiro + RestFul + 微服务
查看>>
Spring Cloud云架构 - SSO单点登录之OAuth2.0 登出流程(3)
查看>>
建站心得之discuz门户程序相比ZBLOG具有哪些优势[图]
查看>>
迭代设计模式
查看>>
编程之美 测试赛 石头剪刀布
查看>>
签名问题
查看>>
如何解决Struts2程序报错:java.lang.ClassCastException
查看>>
LNMP搭建wordpress
查看>>
ASP.NET 中gridview 中的选择按钮取到所选行的关键字段
查看>>
软件开发各阶段交付物列表
查看>>
错误集合
查看>>
Easy-UI 1.3 datagrid 分页大小pageSize设置在IE浏览器的文档模式为9下无效 且页面出现异常...
查看>>
希捷硬盘校准日志分析
查看>>
RHEL6 64位ASM方式安装oracle 11gR2(一)
查看>>
2018-05-24 Linux学习
查看>>
《Python网络编程基础》笔记
查看>>
Oracle数据库之SQL语句练习
查看>>