题目大意

  zjt 是个神仙。

  一天,zjt 正在和 yww 玩猜数游戏。

  zjt 先想一个 \([1,n]\) 之间的整数 \(x\),然后 yww 开始向他问问题。

  yww 每次给 zjt 一个区间 \([l,r](1\leq l\leq r\leq n)\),并询问:\(x\) 是否在区间 \([l,r]\) 内?

  对于 NOIP 爆零的 yww 来说,他只会用二分法去猜出这个数。

  但是 zjt 决定加大难度。他只会在 yww 给出所有想问的问题之后一次性给出答案。

  请你帮助 yww 算出,有多少种可能的区间的集合 \(S\),满足 yww 在询问所有 \(S\) 中的区间的情况下,无论 \(x\) 是多少,yww 都能猜出来。

  方案数对 \(p\) 取模。

  \(n\leq 300,p<2^{30}\)

题解

  考虑求出不满足要求的集合个数。

  对于一个集合 \(S\),求出每一个数被那些区间覆盖了,记为 \(S_i\)。然后给每个数一个编号 \(a_i\),满足 \(S_i\) 相同的数 \(a_i\) 相同。

  对于两个位置 \(a_i=a_j\),如果一个区间覆盖了 \(i\),那么这个区间就一定覆盖了 \(j\)。

  每次把 \(a\) 中的第一个数 \(x\) 放入 \(b\) 的末尾,然后在 \(a\) 中删掉最后一个 \(x\) 前的所有数(包括最后一个 \(x\))。

  例如 \(a=[1,2,3,2,4,2,5,5,10,6,7,8,7,6,9]\)

  此时 \(b=[1,2,5,10,6,9]\)

  可以发现,如果把 yww 给出的没有包含任何数的区间删掉,那么剩下的区间对应着一个长度为 \(\lvert b\rvert\) 的序列的答案。

  而且被删掉的区间是否存在都没有影响。

  这样就可以DP了。

  记 \(f_i\) 为 \(i\) 个数的答案,\(g_{i,j}\) 为 \(i\) 个数,处理之后之剩 \(j\) 个数的答案。

  那么

\[f_i=2^{\binom{i+1}{2}}-\sum_{j=1}^{i-1}f_jg_{i,j}\\
g_{i,j}=g_{i-1,j-1}+\sum_{k=0}g_{i-k-2,j-1}2^{\binom{k+1}{2}}
\]

  时间复杂度:\(O(n^3)\) 或 \(O(n^2\log n)\)

  记 \(F(x)=\sum_{i\geq 0}f_ix^i,G_i(x)=\sum_{j\geq 0}g_{j,i}x^j,H(x)=\sum_{i\geq 0}2^{\binom{i+1}{2}}x^i,A(x)=x+\sum_{i\geq 2}\binom{i-1}{2}x^i\)

  记 \(A^{-1}(x)\) 为 \(A(x)\) 的复合逆:\(A(A^{-1}(x))=x\)

\[G_i(x)=A(x)^i\\
\sum_{j=1}^if_jg_{i,j}=h_i\\
F(A(x))=H(x)\\
F(x)=H(A^{-1}(x))
\]

  然后直接扩展拉格朗日反演求一项的值就好了。

\[[x^n]H(A^{-1}(x))=[x^{-1}](\frac{1}{n}\frac{dH(x)}{dx}\frac{1}{A(x)^n})
\]

  时间复杂度:\(O(n\log n)\)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<functional>
#include<cmath>
#include<vector>
#include<assert.h>
//using namespace std;
using std::min;
using std::max;
using std::swap;
using std::sort;
using std::reverse;
using std::random_shuffle;
using std::lower_bound;
using std::upper_bound;
using std::unique;
using std::vector;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef std::pair<int,int> pii;
typedef std::pair<ll,ll> pll;
void open(const char *s){
#ifndef ONLINE_JUDGE
char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
#endif
}
void open2(const char *s){
#ifdef DEBUG
char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
#endif
}
int rd(){int s=0,c,b=0;while(((c=getchar())<'0'||c>'9')&&c!='-');if(c=='-'){c=getchar();b=1;}do{s=s*10+c-'0';}while((c=getchar())>='0'&&c<='9');return b?-s:s;}
void put(int x){if(!x){putchar('0');return;}static int c[20];int t=0;while(x){c[++t]=x%10;x/=10;}while(t)putchar(c[t--]+'0');}
int upmin(int &a,int b){if(b<a){a=b;return 1;}return 0;}
int upmax(int &a,int b){if(b>a){a=b;return 1;}return 0;}
const int N=510;
int n;
ll p;
ll pw[N*N];
ll f[N];
ll g[N][N];
void init()
{
pw[0]=1;
for(int i=1;i<=n*n;i++)
pw[i]=pw[i-1]*2%p;
}
int main()
{
open("guess");
scanf("%d%lld",&n,&p);
init();
g[0][0]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
{
g[i][j]=g[i-1][j-1];
for(int k=0;i-2-k>=j-1;k++)
g[i][j]=(g[i][j]+g[i-2-k][j-1]*pw[k*(k+1)/2])%p;
}
for(int i=1;i<=n;i++)
{
f[i]=pw[i*(i+1)/2];
for(int j=1;j<i;j++)
f[i]=(f[i]-f[j]*g[i][j])%p;
}
ll ans=f[n];
ans=(ans%p+p)%p;
printf("%lld\n",ans);
return 0;
}

【CSA35G】【XSY3318】Counting Quests DP 拉格朗日反演 NTT的更多相关文章

  1. [拉格朗日反演][FFT][NTT][多项式大全]详解

    1.多项式的两种表示法 1.系数表示法 我们最常用的多项式表示法就是系数表示法,一个次数界为\(n\)的多项式\(S(x)\)可以用一个向量\(s=(s_0,s_1,s_2,\cdots,s_n-1) ...

  2. 【XSY2843】「地底蔷薇」 NTT什么的 扩展拉格朗日反演

    题目大意 给定集合\(S\),请你求出\(n\)个点的"所有极大点双连通分量的大小都在\(S\)内"的不同简单无向连通图的个数对\(998244353\)取模的结果. \(n\le ...

  3. BZOJ 3684: 大朋友和多叉树 [拉格朗日反演 多项式k次幂 生成函数]

    3684: 大朋友和多叉树 题意: 求有n个叶子结点,非叶节点的孩子数量\(\in S, a \notin S\)的有根树个数,无标号,孩子有序. 鏼鏼鏼! 树的OGF:\(T(x) = \sum_{ ...

  4. 【bzoj3684】 大朋友和多叉树 生成函数+多项式快速幂+拉格朗日反演

    这题一看就觉得是生成函数的题... 我们不妨去推下此题的生成函数,设生成函数为$F(x)$,则$[x^s]F(x)$即为答案. 根据题意,我们得到 $F(x)=x+\sum_{i∈D} F^i(x)$ ...

  5. loj#6363. 「地底蔷薇」(拉格朗日反演+多项式全家桶)

    题面 传送门 题解 肝了一个下午--我老是忘了拉格朗日反演计算的时候多项式要除以一个\(x\)--结果看它推倒简直一脸懵逼-- 做这题首先你得知道拉格朗日反演是个什么东西->这里 请坐稳,接下来 ...

  6. bzoj3684: 大朋友和多叉树(拉格朗日反演+多项式全家桶)

    题面 传送门 题解 首先你得知道什么是拉格朗日反演->这里 我们列出树的个数的生成函数 \[T(x)=x+\prod_{i\in D}T^i(x)\] \[T(x)-\prod_{i\in D} ...

  7. [BZOJ3684][拉格朗日反演+多项式求幂]大朋友和多叉树

    题面 Description 我们的大朋友很喜欢计算机科学,而且尤其喜欢多叉树.对于一棵带有正整数点权的有根多叉树,如果它满足这样的性质,我们的大朋友就会将其称作神犇的:点权为\(1\)的结点是叶子结 ...

  8. 【BZOJ3684】大朋友和多叉树(拉格朗日反演)

    题目链接 题意 求满足如下条件的多叉树个数: 1.每一个点的儿子个数在给定的集合 \(S\) 内 2.总的叶子节点树为 \(s\) 儿子之间有顺序关系,但节点是没有标号的. Sol 拉格朗日反演板子题 ...

  9. 洛谷 P5206 - [WC2019]数树(集合反演+NTT)

    洛谷题面传送门 神仙多项式+组合数学题,不过还是被我自己想出来了( 首先对于两棵树 \(E_1,E_2\) 而言,为它们填上 \(1\sim y\) 使其合法的方案数显然是 \(y\) 的 \(E_1 ...

随机推荐

  1. java之servlet入门操作教程一

    这篇文章主要用来记录,进行servlet开发的一些简单操作步骤,帮助直接上手操作 准备: java环境配置:已配置(javac检验) myeclipse开发环境:已安装 tomcat服务器:已安装(或 ...

  2. AspNetCore 基于AOP实现Polly的使用

    前言   说起AOP,其实我们在做MVC/API 的时候应该没少接触,比如说各种的Fitter 就是典型的AOP了. 本来在使用Polly的时候我最初的打算是使用过滤器来实现的,后来发现实现起来相当的 ...

  3. 程序猿想聊天 - 創問 4C 團隊教練心得(二)

    在第二天裡,主要談的是關於 Courage (勇氣) . Co-Create (共創) 的部分因為我們不是真實的團隊,就沒有繼續下去了 一早開始先回顧了一下前一天的內容,接下來我們就開始玩小遊戲 這個 ...

  4. .net 多线程 Thread ThreadPool Task

    先准备一个耗时方法 /// <summary>/// 耗时方法/// </summary>/// <param name="name">< ...

  5. HBase在共享经济互联网业务的应用

    HDFS 与 Hbase HDFS容错率很高,即便是在系统崩溃的情况下,也能够在节点之间快速传输数据.HBase是非关系数据库,是开源的Not-Only-SQL数据库,它的运行建立在Hadoop上.H ...

  6. arcgis api for js入门开发系列十九图层在线编辑

    本篇主要讲述的是利用arcgis api实现图层在线编辑功能模块,效果图如下: 实现思路: 1.arcgis server发布的FeatureServer服务提供的图层在线编辑能力: 2.实现的在线编 ...

  7. 安卓9.0系统机器(亲测有效)激活Xposed框架的步骤

    对于喜欢玩手机的哥们来说,经常会用到xposed框架及其种类繁多功能无敌的模块,对于5.0以下的系统版本,只要手机能获得root权限,安装和激活xposed框架是非常简便的,但随着系统版本的持续更新, ...

  8. (办公)工作中的编码不良习惯Java(不定时更新)

    1.别瞎写,方法里能用封装好的类,就别自己写HashMap. 2.方法名,整的方法名都是啥?退出close,用out. 3.git提交版本,自己写的代码,注释,提交版本的时候,一定要清理掉.每个判断能 ...

  9. 重庆3Shape Dental System技术支持

    Dental System 2014中的一些新的功能:为提高生产力增添了自动冠功能软件会自动根据位置设计冠的形状,以适应周围的牙齿和拮抗剂.新的强大的用户体验优化了工作流程和一个新的重新设计的用户界面 ...

  10. mssql sqlserver with cte表达式(递归)找出最顶值的方法分享

    摘要: 下文通过递归的方式找出最顶级部门的方法分享,如下所示: 实验环境:sql server 2008 R2 下文通过cte-with表达式实现递归,获取一个公司的顶级部门,如下所示 例:部门表 c ...