https://loj.ac/problem/6402

庆祝一下,,,第一个我自己做出来的,,,多项式的题(没办法,我太弱

虽然用了2个小时才想出来,但这毕竟是0的突破……

首先声明,虽然我写的题解很长,但是大部分都是证明和废话

第一步,转化题意(用时30min):

一个1~n的全排列$p$,如果存在$i<j,p[i]<p[j]$,那么就把$i$和$j$之间连一条边。

问所有p的所有排列方案,最后联通块的大小的乘积,的和。

因为原题中$a$是随机的实数,所以说我们可以不用考虑有$a_i=a_j$的情况。

因为最后用到的只有相对的大小关系,所以可以直接转化成一个1~n的排列$p$。

其实很多时间都花在"诶,是这个意思吗,不会啊","哦,不对,看错题了"。

第二步,找规律推性质(用时50min):

我们发现,一个联通块,一定是$l$到$r$连续的一段。

假如说,$a$和$b$在同一个联通块内(令$a<b$),存在$c$满足$a<c<b$,并且$c$不在$a$和$b$所在联通块内。

我们来证明这种情况是不存在的。

首先,$p[b]<p[c]<p[a]$,否则$c$与$a$、$b$有直接的边相连。

那么$p[a]>p[b]$,但是他们在同一个联通块内,

所以一定存在一个位置$x$满足$x<a,p[x]<p[b]$或者$x>b,p[x]>p[a]$

那么$x$一定与$c$直接相连,所以证出矛盾。

同理,我们可以证到一个联通块的$p$也是连续的一段。

但是我不是这么找到这个性质的,因为我上面的方法只是证明了这个性质,但是如果我猜不到这个性质……

我按照套路思考,每个联通块找一个代表员好了,找谁呢,那就$p$最小的那个吧。

我们把点放在一个平面上,第$i$个点的坐标是$(i,p[i])$。

我们按照$p$从小到大,加入每个点。

首先,$p$最小的那个点加入的时候,我们考虑找它所在的联通块的点。

找到一个满足$p[j]>p[i]$的最大的$j$,那么$i$到$j$这个连续区间的所有点都在同一个联通块内。

(把这些点分成$p[x]<p[j]$,$p[x]>p[j]>p[i]$两种情况讨论就可以了)

然后$<i$的一些点,也可能在这个联通块内。

然后我们把这些点删掉,再找到$p$最小的那个点,递归下去。

我们发现,我们把一个n*n的矩形,一次一次的减去一个联通块所在的"势力范围",其实是一次一次砍掉了右边的一条和下面的一条,剩下的还是一个矩形。

如图:

其中淡粉色是一个联通块的势力范围,$t$是这个联通块$p$最大的点,$k$是这个联通块最靠左(就是编号最小)的点。

我们再找下一个联通块的时候,下一个联通块势力范围一定是在白色部分。

所以下一个联通块的$p$最小的点的一定有$p[x]>p[t]$,编号最大的点$x<k$

于是我们两个性质都找到啦。

有了这两个性质之后,我们可以发现,一个联通块$[l,r]$,一定满足:$p[l],p[l+1],....,p[r-1],p[r]$一定是$n-l+1,n-(l+1)+1,....,n-r+1$的一个排列。

同时$p[1],p[2],....,p[r]$一定是$n,n-1,...,n-r+1$的一个排列。

同时$[l,r-1]$中不存在$x$满足$p[1],p[2],....,p[x]$是$n,n-1,....,n-x+1$的一个排列,否则就可以分出$[l,x],[x+1,r]$两个联通块了。

也就是说,如果我们称满足$p[1],p[2],....,p[x]$是$n,n-1,....,n-x+1$的一个排列的$x$是好的,那么每个$x$都一定是一个联通块的右端点。

第三步,推式子(用时40min):

有了上面的几个性质,我们可以开始列$dp$方程了。

我们令$f(n)$表示1~n的一个排列,除$n$位置外,不存在其他位置是好的,的方案数。

那么$f(0)=0,f(1)=1$

$f(n)=n!-\sum\limits_{i=1}^{n-1} i! f(n-i)$

令$g(n)=n!$,特别地,我们规定$g(0)=1$

那么$f(n)=g(n)-\sum\limits_{i=1}^{n-1} g(i) f(n-i)$

把$\sum$移到左边,可以得到$\sum\limits_{i=0}^{n} g(i) f(n-i) = g(n)$

我们发现这是一个卷积形式$f*g+1=g$。(因为$f(0)=0,g(0)=1$)

令$dp(i)$表示前$i$个数,并且$i$是一个联通块右端点,的贡献。规定$dp(0)=1$

枚举上一个联通块的右端点,那么有:

$dp(n)=\sum\limits_{i=0}^{n} (n-i) f(n-i) dp(i)$

令$h(n)=nf(n)$。$h(0)=0$

$dp(n)=\sum\limits_{i=0}^{n} h(n-i) dp(i)$

又是一个卷积形式$dp=dp*h+1$。(因为$h(0)=0,dp(0)=1$)

于是两次多项式求逆就可以解决问题啦。

//Serene
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
using namespace std;
#define ll long long
#define db double
#define For(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i>=(b);--i)
const ll mod=998244353,B=3;
const int maxn=1e7+7;
ll n,g[maxn],h[maxn],ginv[maxn],hinv[maxn],X[maxn]; template<typename T>void read(T& aa) {
aa=0;char cc=getchar();T ff=1;
while((cc!='-')&&(cc<'0'||cc>'9')) cc=getchar();
if(cc=='-') ff=-1,cc=getchar();
while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
aa*=ff;
} ll qp(ll x,ll k) {
ll rs=1;
while(k) {
if(k&1) rs=rs*x%mod;
k>>=1; x=x*x%mod;
}
return rs;
} ll finv(ll x) {return qp(x,mod-2);} ll qp1(ll x,ll k) {
if(k<0) return qp(finv(x),-k);
return qp(x,k);
} void Rader(ll F[],ll len) {
for(int i=1,j=len>>1,k;i<len-1;++i) {
if(i<j) swap(F[i],F[j]);
k=len>>1;
while(j>=k) {j-=k;k>>=1;}
if(j<k) j+=k;
}
} void FFT(ll F[],ll len,ll on) {
Rader(F,len);
for(int h=2;h<=len;h<<=1) {
ll wn=qp1(B,(mod-1)*on/h);
for(int j=0;j<len;j+=h) {
ll w=1;
for(int i=j;i<j+h/2;++i) {
ll u=F[i],v=w*F[i+h/2]%mod;
F[i]=(u+v)%mod;
F[i+h/2]=(u-v+mod)%mod;
w=w*wn%mod;
}
}
}
ll x=finv(len);
if(on==-1) For(i,0,len) F[i]=F[i]*x%mod;
} void get_inv(ll N,ll* A,ll* B) {
if(N==1) {
B[0]=finv(A[0]);
return;
}
get_inv((N+1)>>1,A,B);
ll n=1;for(;n<=(N<<1);n<<=1);
For(i,0,N-1) X[i]=A[i]; For(i,N,n) X[i]=B[i]=0;
FFT(X,n,1); FFT(B,n,1);
For(i,0,n) B[i]=B[i]*(2-B[i]*X[i]%mod+mod)%mod;
FFT(B,n,-1); For(i,N,n) B[i]=0;
} int main() {
read(n);
g[0]=1; For(i,1,n) g[i]=g[i-1]*(ll)i%mod;
get_inv(n+1,g,ginv);
For(i,1,n) h[i]=ginv[i]*(ll)i%mod;
h[0]=1;
get_inv(n+1,h,hinv);
printf("%lld\n",hinv[n]);
return 0;
}

loj6402 校门外的树(dp,多项式求逆)的更多相关文章

  1. CF848E Days of Floral Colours——DP+多项式求逆/分治NTT

    官方题解:http://codeforces.com/blog/entry/54233 就是由简入繁 1.序列处理,只考虑一个半圆 2.环形处理(其实这个就是多了旋转同构) 然后基于分割线邻居的跨越与 ...

  2. BZOJ 3456: 城市规划(dp+多项式求逆)

    传送门 解题思路 这道题就是求带标号的无向连通图个数,首先考虑\(O(n^2)\)的做法,设\(f_i\)表示有\(i\)个节点的无向连通图个数,那么考虑容斥,先把所有的无向图求出,即为\(2^{C( ...

  3. 【bzoj3456】城市规划 dp+多项式求逆

    Description 刚刚解决完电力网络的问题, 阿狸又被领导的任务给难住了. 刚才说过, 阿狸的国家有n个城市, 现在国家需要在某些城市对之间建立一些贸易路线, 使得整个国家的任意两个城市都直接或 ...

  4. LOJ #6402. yww 与校门外的树 多项式求逆

    蛮神的一道题. code: #include <cmath> #include <cstring> #include <algorithm> #include &l ...

  5. BZOJ 3456: 城市规划 与 多项式求逆算法介绍(多项式求逆, dp)

    题面 求有 \(n\) 个点的无向有标号连通图个数 . \((1 \le n \le 1.3 * 10^5)\) 题解 首先考虑 dp ... 直接算可行的方案数 , 容易算重复 . 我们用总方案数减 ...

  6. [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)

    [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...

  7. P1047 校门外的树

    P1047 校门外的树 题目描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0 ...

  8. Vijos1448校门外的树 题解

    Vijos1448校门外的树 题解 描述: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现 ...

  9. OpenJudge计算概论-校门外的树

    /*======================================================================== 校门外的树 总时间限制: 1000ms 内存限制: ...

随机推荐

  1. 解决在Spring整合Hibernate配置tx事务管理器出现错误的问题

    问题描述: Error occured processing XML 'org/aopalliance/intercept/MethodInterceptor'. See Error Log for ...

  2. printk函数打开和关闭消息

    在驱动开发的早期, printk 非常有助于调试和测试新代码. 当你正式发行驱动时, 换句 话说, 你应当去掉, 或者至少关闭, 这些打印语句. 不幸的是, 你很可能会发现, 就在你 认为你不再需要这 ...

  3. T2980 LR棋盘【Dp+空间/时间优化】

    Online Judge:未知 Label:Dp+滚动+前缀和优化 题目描述 有一个长度为1*n的棋盘,有一些棋子在上面,标记为L和R. 每次操作可以把标记为L的棋子,向左移动一格,把标记为R的棋子, ...

  4. Leetcode187. Repeated DNA Sequences重复的DNA序列

    所有 DNA 由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:"ACGAATTCCG".在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助. 编写一个函数 ...

  5. 学习 debug

    要在代码编辑器中设置源代码断点,有以下 4 种操作方式. (1) 把光标移到要设为断点的行上,按下 F5 键. (2) 用鼠标左键单击要设为断点的行的最左端. (3) 用鼠标右键单击要设为断点的行,在 ...

  6. laydate实现设置最小时间为当前时间

    当前时间之前的日期不能选择,添加个min,主要代码如下: var now = new Date(); startTime= laydate.render({ elem: '#test1', type: ...

  7. AutoIt自动化编程(4)【转】

    五.自动化操作轻松入门系列5 控件操作 然而,在真正实现自动化时仅靠上面的技术往往难以达到预期目的.下面开始进入最为重要的控件操作. 1.设置文本 在安装软件的过程中用户往往需要提供一些必需信息,比如 ...

  8. windows安装apache系统中无apache2服务解决方案

    一直都是用WIN开发PHP,今天有用户反映SHUGUANG CMS在APACHE+PHP中不能正常运行,只好自己机器配置个环境测试(http://xz.8682222.com)遇到点小问题,搜索相关资 ...

  9. Python面向对象学习

    以下面例子作为面向对象基础介绍,类比java里的面向对象既可以,大同小异 class Employee(): raiseAmount=1.04 employeeNum= def __init__(se ...

  10. webpack 配置分离css插件

    以css配置示例,less与sass同理 1. 使用旧版的ExtractTextPlugin插件 安装 npm install extract-text-webpack-plugin@next --s ...