首先显然的是,题中所给出的n个区间要么互相包含,要么相离,否则一定不合法。

然后我们可以对于直接包含的关系建出一棵树,于是现在的问题就是给n个节点分配权值,使其去掉最后一个点后不存在非平凡(长度大于1)的连续区间。

我们发现这个方案数和不存在不经过最大(小)值的非平凡连续区间的排列数是等价的。

于是我们考虑$f[n]$为长度为$n+1$的答案,我们考虑去掉最小值。

如果合法,那么必然是$f[n-1]$中的一种情况,而这时我们要将最小值插进去,我们发现,只要不插在次小值旁边就都是合法的,于是这部分的贡献就是$(n-1) \cdot f[n-1]$。

否则,我们考虑去掉后的序列中的极长的不经过最大值的非平凡连续区间长度为i,我们现在要将最小值插进去,然后满足这里面离散后没有一个不经过最小值的非平凡连续区间,这是$f[i]$,然后这段区间权值的取值可以取遍$3~n$,就有$n-i-1$种方案,然后我们把他缩成一个点,现在要剩下的点合法,就是$f[n-i]$,这部分的贡献就是$\sum_{i=2}^{n-2}{f[i] \cdot f[n-i] \cdot (i-1)}$

然后就可以愉快的cdq+fft啦。

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
#define mod 998244353
#define N 133333
using namespace std;
int f[N],T,n,l[N],q[N],top,ans,cnt,flag;
int len,inv,rev[N],a[N],b[N],tmp1[N],tmp2[N];
int qp(int a,int b){
int c=;
for(;b;b>>=,a=1ll*a*a%mod)
if(b&)c=1ll*c*a%mod;
return c;
}
void UPD(int &a,int b){a=(a+b>=mod)?(a+b-mod):(a+b);}
void ntt(int *a,int o){
register int i,j,k,dan,now,t;
for(i=;i<len;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
for(k=;k<=len;k<<=){
dan=qp(,o==?(mod-)/k:(mod--(mod-)/k));
for(i=;i<len;i+=k){
now=;
for(j=;j<(k>>);j++,now=1ll*now*dan%mod){
t=1ll*a[i+j+(k>>)]*now%mod;
a[i+j+(k>>)]=(a[i+j]-t+mod)%mod;
a[i+j]=(a[i+j]+t)%mod;
}
}
}
if(o==-){for(i=;i<len;i++)a[i]=1ll*a[i]*inv%mod;}
}
void mul(int *a,int *b,int *c,int l1,int l2){
for(len=;len<=l1+l2;len<<=);
for(int i=;i<len;i++){
if(i&)rev[i]=(rev[i>>]>>)|(len>>);
else rev[i]=rev[i>>]>>;
}
inv=qp(len,mod-);
for(int i=;i<l1;i++)tmp1[i]=a[i];
for(int i=l1;i<len;i++)tmp1[i]=;
for(int i=;i<l2;i++)tmp2[i]=b[i];
for(int i=l2;i<len;i++)tmp2[i]=;
ntt(tmp1,);ntt(tmp2,);
for(int i=;i<len;i++)c[i]=1ll*tmp1[i]*tmp2[i]%mod;
ntt(c,-);
}
void cdq(int l,int r){
if(l==r){
UPD(f[l],1ll*f[l-]*(l-)%mod);
return ;
}
int mid=(l+r)>>;
cdq(l,mid);
for(int i=l;i<=mid;i++){
a[i-l]=1ll*f[i]*(i-)%mod;
b[i-l]=f[i];
}
mul(a,b,a,mid-l+,mid-l+);
for(int i=max(l<<,mid+);i<=r;i++)
UPD(f[i],a[i-(l<<)]);
if(l!=){
for(int i=;i<=min(l-,r-l);i++)a[i-]=f[i];
for(int i=l;i<=mid;i++)b[i-l]=f[i];
mul(a,b,a,min(l-,r-l)-,mid-l+);
for(int i=max(l+,mid+);i<=r;i++)
UPD(f[i],1ll*a[i-l-]*(i-)%mod);
}
cdq(mid+,r);
}
int main(){
scanf("%d%d",&T,&n);
f[]=;f[]=;
cdq(,n-);
while(T--){
ans=;top=;
for(int i=;i<=n;i++)
scanf("%d",&l[i]);
if(l[n]!=n){puts("");continue;}
for(int i=;i<=n;i++){
cnt=flag=;
while(top&&i-l[i]+<=q[top]){
if(i-l[i]+>q[top]-l[q[top]]+){flag=;break;}
top--,cnt++;
}
if(flag==)break;
ans=1ll*ans*f[cnt]%mod;
q[++top]=i;
}
if(flag)puts("");
else printf("%d\n",ans);
}
}

bzoj5342 CTSC2018 Day1T3 青蕈领主的更多相关文章

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

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

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

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

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

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

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

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

  5. [CTSC2018]青蕈领主

    [CTSC2018]青蕈领主 题解 首先,连续段要知道结论: 连续段要么不交,要么包含 所以是一棵树!每个位置的father是后面第一个包含它的 树形DP! 设dp[x],x为根的子树,(设管辖的区间 ...

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

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

  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. python 3下基于select模型的事件驱动机制程序

    它的基本原理就是select/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程.它的流程如图: 当用户进程调用了select,那么整个 ...

  2. php中$_FILES应用实例

    允许用户从表单上传文件是非常有用的.先来看一段HTML表单代码 <html> <body> <form action="upload_file.php" ...

  3. 用Maven实现一个protobuf的Java例子

    注:试验环境在Mac Idea环境下 1. 介绍Protocol Buffers Protocal Buffers(简称protobuf)是谷歌的一项技术,用于结构化的数据序列化.反序列化,常用于RP ...

  4. mybatis源码解读(四)——事务的配置

    上一篇博客我们介绍了mybatis中关于数据源的配置原理,本篇博客介绍mybatis的事务管理. 对于事务,我们是在mybatis-configuration.xml 文件中配置的: 关于解析 < ...

  5. THINKPHP 调试------输出sql语句

    echo $model->getLastSql();//$model为实例化的模板类

  6. Maven项目管理工具

    Maven项目管理工具 白面郎君 Svn eclipse maven量级 1 Maven的简介 1.1 什么是maven 是apache下的一个开源项目,是纯java开发,并且只是用来管理java项目 ...

  7. Java并发之ReentrantLock

    一.ReentrantLock简介 ReentrantLock字面意义上理解为可重入锁.那么怎么理解可重入这个概念呢?或者说和我们经常用的synchronized又什么区别呢? ReentrantLo ...

  8. JS 数据类型、赋值、深拷贝和浅拷贝

    js 数据类型 六种 基本数据类型: Boolean. 布尔值,true 和 false. null. 一个表明 null 值的特殊关键字. JavaScript 是大小写敏感的,因此 null 与 ...

  9. QT中的相对位置,绝对位置之间的转换(maptoglobal,mapfromglobal)

    1. 相对位置:每个Qwidget都能通过pos()获取到相对自己父类窗口的位置, 2. 绝对位置:pWidget->mapToGlobal(QPoint(0,0)) ;将当前控件的相对位置转换 ...

  10. 6个常见的php安全攻击

    1.SQL注入 SQL注入是一种恶意攻击,用户利用在表单字段输入SQL语句的方式来影响正常的SQL执行.还有一种是通过system()或exec()命令注入的,它具有相同的SQL注入机制,但只针对sh ...