首先显然的是,题中所给出的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. C++笔记十七:C语言中 “冒牌货”const和const符号表

      在.c文件中有程序: int main() { int const a = 10; a=20; printf("a=%d\n",a); return 0; } 编译就知道C语言 ...

  2. oracle 数据库 date + 1 转载

    http://blog.csdn.net/yjp198713/article/details/18131871 oracle 求两个时间点直接的分钟.小时数 1.获得时间差毫秒数: select ce ...

  3. access窗口标签居中

    Private Sub Form_Resize() On Error Resume Next Me.Width = Me.InsideWidth Me.Section(acDetail).Height ...

  4. redis+twemproxy实现redis集群

    Redis+TwemProxy(nutcracker)集群方案部署记录 转自: http://www.cnblogs.com/kevingrace/p/5685401.html Twemproxy 又 ...

  5. Day10 多线程理论 开启线程

    多线程: 多线程和多进程的不同是他们占用的资源不一样, 一个进程里边可以包含一个或多个进程, 进程的开销大,线程的开销小. 打个比方来说:创建一个进程,就是创建一个车间.创建一个线程,就是在一个车间创 ...

  6. Future与Promise

    https://code.csdn.NET/DOC_Scala/chinese_scala_offical_document/file/Futures-and-Promises-cn.md#ancho ...

  7. C语言实现输出一组数字中的所有奇数

    /*第二题*/ #include<stdio.h> //输入186732468 //输出173 //输入12345677 //输出13577 main(){ ;//输入的数字,数字的长度 ...

  8. python都能做什么

    一.python: Python具有丰富和强大的库.它常被昵称为胶水语言,能够把用其他语言制作的各种模块(尤其是C/C++)很轻松地联结在一起.常见的一种应用情形是,使用Python快速生成程序的原型 ...

  9. Python人脸识别最佳教材典范,40行代码搭建人脸识别系统!

    Face Id是一款高端的人脸解锁软件,官方称:"在一百万张脸中识别出你的脸."百度.谷歌.腾讯等各大企业都花费数亿来鞭策人工智能的崛起,而实际的人脸识别技术是否有那么神奇? 绿帽 ...

  10. 源码安装xadmin及使用

    xadmin是django的第三方后台 我们也可以使用pip来安装,但是推荐使用源码安装. 因为有些新功能以及发布在GitHub上,但是还未发布到pypi上,我们就可以提取使用这些功能. 一.安装 1 ...