题目大意

  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. DS控件库 DS按钮多种样式

    在DS控件库(DSControls)中,DS按钮的功能非常多,通过设置不同的属性值来使按钮呈现不同的效果.DS按钮的常用属性如下: 使用不同的属性调出不同的外观样式示例

  2. .net core EFcore model生成数据

    创建数据库 (扫盲贴还劳烦大神们勿喷,谢谢) 打开数据库 输入如下代码 创建数据库 CREATE DATABASE [Blogging]; GO USE [Blogging]; GO CREATE T ...

  3. NLog组件

    接触.net项目的同志们都清楚,最初在项目中记录日志常用的是log4net日志组件,随着.net框架的不对优化升级,最近新流行的日志框架nlog,下面我就对nlog组件说说自己的认知: 下载 通过Nu ...

  4. 数据库缓存mybatis,redis

    简介 处理并发问题的重点不在于你的设计是怎样的,而在于你要评估你的并发,并在并发范围内处理.你预估你的并发是多少,然后测试r+m是否支持.缓存的目的是为了应对普通对象数据库的读写限制,依托与nosql ...

  5. JavaScript中的十个难点,你有必要知道。

    1. 立即执行函数 立即执行函数,即Immediately Invoked Function Expression (IIFE),正如它的名字,就是创建函数的同时立即执行.它没有绑定任何事件,也无需等 ...

  6. web前端图片上传(2)

    今天发现了一种ajax上传图片的方式,是以前没有用过的,首先来说下为什么要用这种方式.是因为原来后台是用的form表单的方式来提交表单数据的.但是觉得呢,这种方式不太好,因为要刷新页面,前台只用控制台 ...

  7. vue 项目中引用百度地图

    新建map.js export const BaiduMap = { init: function() { const BMapURL = 'https://api.map.baidu.com/api ...

  8. ubuntu server 16.04 开启root密码登录

    0x00 ubuntu server 16.04 开启root密码登录 由于众多VPS默认使用证书验证登录,虽然安全但使用十分不便,所以特提供开启root用户并使用密码登录方法. 0x01 为root ...

  9. Java Web相关问题

     关于这两天主要问题的解答: (1) 驱动程序无法使用安全套接字层(SSL)加密与 SQL Server 建立安全连接.错误: java.lang.RuntimeException: Could no ...

  10. Redis中5种数据结构的使用场景

    一.redis 数据结构使用场景 原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 ...