[CTSC2018]青蕈领主

题解

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

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

所以是一棵树!每个位置的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<bits/stdc++.h>
#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<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>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=;
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-){int ret=;while(y){if(y&) ret=mul(x,ret);x=mul(x,x);y>>=;}return ret;}
template<class ...Args>il int ad(const int a,const int b,const Args &...args) {return ad(ad(a,b),args...);}
template<class ...Args>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=+;
const int G=;
const int GI=;
int n,T;
int L[N];
struct Poly{
vector<int>f;
Poly(){f.clear();}
il int &operator[](const int &x){assert(x<f.size());return f[x];}
il void resize(int n){f.resize(n);}
il int size(){return f.size();}
il void clear(){f.clear();}
il void out(){for(reg i=;i<(int)f.size();++i) ot(f[i]);putchar('\n');}
}f;
int rev[*N];
int init(int n){
int m=;
for(m=;m<n;m<<=);
for(reg i=;i<m;++i){
rev[i]=(rev[i>>]>>)|((i&)?m>>:);
}
return m;
}
void NTT(Poly &f,int c){
int n=f.size();
for(reg i=;i<n;++i){
if(i<rev[i]) swap(f[i],f[rev[i]]);
}
for(reg p=;p<=n;p<<=){
int gen;
if(c==) gen=qm(G,(mod-)/p);
else gen=qm(GI,(mod-)/p);
for(reg l=;l<n;l+=p){
int buf=;
for(reg i=l;i<l+p/;++i){
int tmp=mul(f[i+p/],buf);
f[i+p/]=ad(f[i],mod-tmp);
f[i]=ad(f[i],tmp);
buf=mul(buf,gen);
}
}
}
if(c==-){
int iv=qm(n);
for(reg i=;i<n;++i){
f[i]=mul(f[i],iv);
}
}
}
il Poly operator *(Poly F,Poly G){
int n=init(F.size()+G.size()-);
F.resize(n);G.resize(n);
NTT(F,);NTT(G,);
for(reg i=;i<n;++i) F[i]=mul(F[i],G[i]);
NTT(F,-);
return F;
}
void divi(int l,int r){ if(l==&&r==){
f[]=;f[]=;return;
}
if(l==r){
f[l]=ad(f[l],mod-mul(f[],f[l-],l-));
f[l]=ad(f[l],mul(l-,f[l-]));
return;
}
int mid=(l+r)>>;
divi(l,mid);
// cout<<" divi ---------------------------"<<l<<" "<<r<<endl;
Poly F,G,K;
if(l==){
// goto s;
// cout<<"sol1---- "<<endl;
F.resize(mid+);
G.resize(mid+);
for(reg i=;i<=mid;++i){
F[i]=f[i];
G[i]=mul(f[i],i-);
}
// F.out();
// G.out();
// cout<<"hahahaha "<<endl;
F=F*G;
// F.out(); for(reg i=mid+;i<=r;++i){
f[i]=ad(f[i],F[i]);
}
// cout<<" over "<<endl;
}else{ // cout<<"sol2**** "<<endl;
F.resize(mid-l+);
G.resize(r-l+);
for(reg i=;i<=mid-l;++i){
F[i]=f[i+l];
}
for(reg i=;i<=r-l;++i){
G[i]=mul(f[i],i-);
}
// F.out();
// G.out();
// cout<<" mul "<<endl;
K=F*G;
// cout<<" K "<<endl;
// K.out(); for(reg i=mid+;i<=r;++i){
f[i]=ad(f[i],K[i-l]);
} F.clear();G.clear();
F.resize(mid-l+);G.resize(r-l+); // cout<<F.size()<<" len "<<mid-l+1<<endl;
for(reg i=;i<=mid-l;++i){
F[i]=mul(f[i+l],i+l-);
}
// cout<<" OK ? "<<endl;
for(reg i=;i<=r-l;++i){
G[i]=f[i];
} K=F*G;
for(reg i=mid+;i<=r;++i){
f[i]=ad(f[i],K[i-l]);
}
}
// s:;
// cout<<" end "<<f[3]<<endl;
divi(mid+,r);
}
int sta[N],top;
int main(){
rd(T);rd(n);
int m=init(n+);
f.resize(m); divi(,m-);
// f.out(); while(T--){
for(reg i=;i<=n;++i) rd(L[i]);
top=;
if(L[n]!=n) {
puts("");continue;
}
int ans=;
bool fl=true;
for(reg i=;i<=n;++i){
int son=;
while(top&&sta[top]-L[sta[top]]+>=i-L[i]+) ++son,--top;
// cout<<" ii "<<i<<" son "<<son<<endl;
if(top){
if(sta[top]>=i-L[i]+) fl=false;
}
sta[++top]=i;
ans=mul(ans,f[son]);
}
if(!fl) ans=;
printf("%d\n",ans);
}
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
*/

树形结构!

然后递归为子问题。

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

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

[CTSC2018]青蕈领主的更多相关文章

  1. 并不对劲的bzoj5342:loj2554:uoj401:p4566: [Ctsc2018]青蕈领主

    题目大意 \(T\)(\(T\leq100\))组询问 有\(1\)到\(n\)(\(n\leq50000\))这\(n\)个整数组成的一个排列 定义这个排列的一个子区间是"连续" ...

  2. Loj #2554. 「CTSC2018」青蕈领主

    Loj #2554. 「CTSC2018」青蕈领主 题目描述 "也许,我的生命也已经如同风中残烛了吧."小绿如是说. 小绿同学因为微积分这门课,对"连续"这一概 ...

  3. uoj#401. 【CTSC2018】青蕈领主(分治FFT)

    传送门 话说分治\(FFT\)是个啥子啊--还有题目里那字好像念(蕈xùn) 首先考虑无解的情况:区间相交或者\(L_n\neq n\) 这两个都可以感性理解一下 所以区间之间只会有包含关系,我们把每 ...

  4. bzoj5342 CTSC2018 Day1T3 青蕈领主

    首先显然的是,题中所给出的n个区间要么互相包含,要么相离,否则一定不合法. 然后我们可以对于直接包含的关系建出一棵树,于是现在的问题就是给n个节点分配权值,使其去掉最后一个点后不存在非平凡(长度大于1 ...

  5. UOJ#401. 【CTSC2018】青蕈领主 分治,FFT

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ401.html 题解 首先,对于一个排列,它的连续段一定只有包含关系,没有相交关系. 我们可以据此得到一棵表示连续段的树. ...

  6. LOJ 2554 「CTSC2018」青蕈领主——结论(思路)+分治FFT

    题目:https://loj.ac/problem/2554 一个“连续”的区间必然是一个排列.所有 r 不同的.len 最长的“连续”区间只有包含.相离,不会相交,不然整个是一个“连续”区间. 只有 ...

  7. CTSC2018 & APIO2018 颓废 + 打铁记

    CTSC2018 & APIO2018 颓废 + 打铁记 CTSC 5 月 6 日 完美错过报道,到酒店领了房卡放完行李后直接奔向八十中拿胸牌.饭票和资料.试机时是九省联考的题,从来没做过,我 ...

  8. [冬令营模拟]GTSG2018

    上学期没有去 GTSG,于是今天老师让我们来做一下 GTSG2018 Day1 & Day3 Day1 在上午当成一场考试来搞了,Day3 由于锅太多而且 T3 玄学而被放到下午自学... 上 ...

  9. GOOD BYE OI

    大米饼正式退役了,OI给我带来很多东西 我会的数学知识基本都在下面了 博客园的评论区问题如果我看到了应该是会尽力回答的... 这也是我作为一个OIer最后一次讲课的讲稿 20190731 多项式乘法 ...

随机推荐

  1. 微信小程序picker下拉绑定数据

    页面部分 <picker mode = "selector" bindchange="bindPickerChange" value="{{pr ...

  2. activeMQ的回顾

    JMS: JMS基本概念: JMS(Java Message Service) 即Java消息服务.它提供标准的产生.发送.接收消息的接口简化企业应用的开发.它支持两种消息通信模型:点到点(point ...

  3. 深度探索C++对象模型读书笔记-第七章站在对象模型的尖端

    Template 模板是在编译时期而非执行时期被计算的.因此其不会带来效率的降低. 1: const Point<float> &ref = 0; 该语句会实例化一个Point的f ...

  4. Apache 环境变量配置

    在path 中加入  C:\__S_D_K__\AndroidApache\apache-ant-1.9.14\bin 我的路径在C盘

  5. java.lang.InstantiationException: com.lch.commder.entity.Car 已解决

    以上的上异常,是你的类实例化对象失败的时候抛出异常,这种异常多会出现在抽象类中,在使用反射的机制时,解决方法很简单 在你的类中再加一个空构造方法

  6. jQuery.speech实现文本转语音播报功能

    先放一个实例的地址https://github.com/wenco/speech jQuery.speech是用jQuery写的扩展插件,主要是用来语音播报. 接口调用百度翻译的接口,所以存在url参 ...

  7. Noip 2012 day2t1 同余方程

    Description 求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解. Input 输入文件为mod.in. 输入只有一行,包含两个正整数 a, b,用一个空格隔开. Output 输 ...

  8. 基于Netty的RPC架构学习笔记(三):netty客户端

    文章目录 举个

  9. 27. USART, Universal synchronous asynchronous receiver transmitter

    27.1 USART introduction 通用同步异步接收发射机(USART)对需要NRZ异步串行数据格式行业标准的外部设备,提供了一个灵活的全双工数据交换的方法.USART使用分数波特率生成器 ...

  10. CodeForces 1152F1 Neko Rules the Catniverse (Small Version)

    题目链接:http://codeforces.com/problemset/problem/1152/F1 题目大意 有 n 个星球,给定限制 m,从 x 星球走到 y 星球的条件是,$1 \leq ...