【LOJ6363】「地底蔷薇」【点双】【指数型生成函数】【扩展拉格朗日反演】【多项式幂函数】

传送门

题意:给定nnn和集合SSS,求出nnn个点的「所有极大点双连通分量的大小都在SSS 内」的不同简单无向连通图的个数 模 998244353998244353998244353

n,∑i∈Si≤105n,\sum_{i\in S}i \leq10^5n,iSi105

道理我都懂,可为啥我百度搜地灵殿ex终符一半都是cookie☆同人OI题

思路挺清奇的

首先注意题目中的点双定义是不存在割点,也就是说只有两个点的连通图也是点双

同时一个点可能属于多个点双

显然要设出答案的EGF

因为无向图关系很复杂,所以我们要强行整点东西上去

[xn]F(x)[x^n]F(x)[xn]F(x)表示 nnn个点 带标号 有根 满足题目条件 的方案数 的EGF

有根是指:每张图钦定一个根,如果两张图边完全相同但根不同也视为不同的图

其实就是乘一个nnn

考虑怎么表示出F(x)F(x)F(x)

对于一张有根图,我们把根删掉,这样会出现多个连通块

对于每个连通块,会发现都会有若干点和根处于同一个点双内

但是不会有不同连通块的点处于同一点双,因为根结点删去后它们分开了,与定义矛盾

考虑一个连通块的情况

先考虑根结点所在的点双大小,发现同一组点组成的点双也有多种连边方案

ana_nan表示n+1n+1n+1个点构成的带标号点双个数

再设出满足题目要求的点双的EGF

A(x)=∑i+1∈Saii!xiA(x)=\sum_{i+1\in S}\frac{a_i}{i!}x^iA(x)=i+1Si!aixi

因为没有跨连通块,所以这个连通块的点双一定在SSS

然后将点双中的所有边删掉,这样点双中的点两两间都不会连通 因为如果连通,由于内部边都断完了,只能走外面的点,而经过的点都会在这个点双内

也就是说,这个大连通块被分成了若干小连通块,且连通块个数等于点双的大小(不含根),小连通块的根是原来的点双中的点

这样可以写出一个大连通块的EGF

∑i=1∞aii!Fi(x)\sum_{i=1}^{\infin}\frac{a_i}{i!}F^i(x)i=1i!aiFi(x)

也就是A(F(x))A(F(x))A(F(x))

注意:这个过程并没有选出点双中有哪些点,只是把连通块中的点分组并将每组的根按点双的方式连接起来

然后F(x)F(x)F(x)可以表示成任意个数连通块组合再加上根

也就是

F(x)=xeA(F(x))F(x)=xe^{A(F(x))}F(x)=xeA(F(x))

假设我们已经求出了A(x)A(x)A(x),我们尝试算出F(x)F(x)F(x)

F(x)eA(F(x))=x{F(x)\over e^{A(F(x))}}=xeA(F(x))F(x)=x

f(F(x))=F(x)eA(F(x))=xf(F(x))={F(x)\over e^{A(F(x))}}=xf(F(x))=eA(F(x))F(x)=x

fffFFF互为复合逆

f(x)=xeA(x)f(x)=\frac{x}{e^{A(x)}}f(x)=eA(x)x

显然[x0]A(x)=0[x^0]A(x)=0[x0]A(x)=0,所以可以算出f(x)f(x)f(x),进而用拉格朗日反演算出[xn]F(x)[x^n]F(x)[xn]F(x)


现在的问题是如何求A(x)A(x)A(x)

直接求不好求,考虑构造一个相似的问题用其他方法算一次,再把A(x)A(x)A(x)反推回来

那考虑减少限制 发现减掉在SSS中的限制,也就是任意连通图,我们也可以用这个思路计算

并且这是一道原题

城市规划

直接取对数就可以轻松算出答案,岂不美哉?

好,我们仿(fu)照(zhi)这道题,算出任意无向连通图的EGF G(x)G(x)G(x),并乘一个nnn上个根

现在G(x)G(x)G(x) 已知了

B(x)=∑i=1∞aii!xiB(x)=\sum_{i=1}^{\infin} \frac{a_i}{i!}x^iB(x)=i=1i!aixi

相同的思路,得到

G(x)=xeB(G(x))G(x)=xe^{B(G(x))}G(x)=xeB(G(x))

G(x)eB(G(x))=x\frac{G(x)}{e^{B(G(x))}}=xeB(G(x))G(x)=x

g(G(x))=G(x)eB(G(x))=xg(G(x))=\frac{G(x)}{e^{B(G(x))}}=xg(G(x))=eB(G(x))G(x)=x

g(x)=xeB(x)g(x)=\frac{x}{e^{B(x)}}g(x)=eB(x)x

变一下可以得到

B(x)=ln⁡(xg(x))B(x)=\ln(\frac{x}{g(x)})B(x)=ln(g(x)x)

用拉格朗日反演算出g(x)g(x)g(x)……

拉个鬼啊,一次拉格朗日反演就是O(nlogn)O(nlogn)O(nlogn)的,你要算出g(x)g(x)g(x)就要跑nnn次,再怎么也有O(n2)O(n^2)O(n2)了吧

但我们注意到A(x)A(x)A(x)有值的地方很少,而且下标和不超过1e51e51e5,所以如果我们直接拉出A(x)A(x)A(x)就没有复杂度问题啦

好,整理一下已知条件

g(G(x))=G(x)eB(G(x))=xg(G(x))=\frac{G(x)}{e^{B(G(x))}}=xg(G(x))=eB(G(x))G(x)=x

B(x)=ln⁡(xg(x))B(x)=\ln(\frac{x}{g(x)})B(x)=ln(g(x)x)

闲着没事把上面代到下面

(注:这里为了统一代码改一下)

B(G(g(x)))=ln⁡(xg(x))B(G(g(x)))=\ln(\frac{x}{g(x)})B(G(g(x)))=ln(g(x)x)

好多括号啊,拆掉里面那个

B(G(x))=ln⁡(G(x)x)B(G(x))=\ln(\frac{G(x)}{x})B(G(x))=ln(xG(x))


停,我说一句

有个叫扩展拉格朗日反演的东西,长这样:

[xn]H(G(x))=1n[x−1]H′(x)Fn(x)[x^n]H(G(x))=\frac{1}{n}[x^{-1}]\frac{H'(x)}{F^n(x)}[xn]H(G(x))=n1[x1]Fn(x)H(x)

证明的话在G(F(x))=xG(F(x))=xG(F(x))=x两边同时复合一个H(x)H(x)H(x),并令H(G(x))=T(x)H(G(x))=T(x)H(G(x))=T(x),后面就一模一样了


好继续

我们强行构造上面的结论,令

H(g(x))=B(x)H(g(x))=B(x)H(g(x))=B(x)

这样

[xn]B(x)=[xn]H(g(x))=1n[x−1]H′(x)Gn(x)[x^n]B(x)=[x^n]H(g(x))=\frac{1}{n}[x^{-1}]\frac{H'(x)}{G^n(x)}[xn]B(x)=[xn]H(g(x))=n1[x1]Gn(x)H(x)

就可以把B(x)B(x)B(x)算出来

现在只需要求出H(x)H(x)H(x)

由于

H(g(x))=B(x)H(g(x))=B(x)H(g(x))=B(x)

得到

H(x)=H(g(G(x)))=B(G(x))=ln⁡(G(x)x)H(x)=H(g(G(x)))=B(G(x))=\ln(\frac{G(x)}{x})H(x)=H(g(G(x)))=B(G(x))=ln(xG(x))

并不需要手动算,除出来O(n)O(n)O(n)挪一下就可以了

把读入的位置拉出来直接丢到A(x)A(x)A(x)的对应位置,然后推出F(x)F(x)F(x)即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <ctime>
#define MAXN 400005
using namespace std;
const int MOD=998244353;
inline int read()
{int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans;
}
typedef long long ll;
inline int add(const int& x,const int& y){return x+y>=MOD? x+y-MOD:x+y;}
inline int dec(const int& x,const int& y){return x<y? x-y+MOD:x-y;}
inline int qpow(int a,int p)
{int ans=1;while (p){if (p&1) ans=(ll)ans*a%MOD;a=(ll)a*a%MOD;p>>=1;}return ans;
}
#define inv(x) qpow(x,MOD-2)
int fac[MAXN],finv[MAXN];
int rt[2][24];
int l,r[MAXN];
inline void init(){for (int i=0;i<(1<<l);i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));}
inline void NTT(int* a,int type)
{int lim=1<<l;for (int i=0;i<lim;i++) if (i<r[i]) swap(a[i],a[r[i]]);for (int L=0;L<l;L++){int mid=1<<L,len=mid<<1,Wn=rt[type][L+1];for (int s=0;s<lim;s+=len)for (int k=0,w=1;k<mid;k++,w=(ll)w*Wn%MOD){int x=a[s+k],y=(ll)w*a[s+mid+k]%MOD;a[s+k]=add(x,y);a[s+mid+k]=dec(x,y);}}if (type){int t=inv(lim);for (int i=0;i<lim;i++) a[i]=(ll)a[i]*t%MOD;}
}
void getinv(int* A,int* B,int n)
{static int f[MAXN],t[MAXN];if (n==1) return (void)(*B=inv(*A));getinv(A,t,(n+1)>>1);for (l=0;(1<<l)<(n<<1);l++);init();for (int i=0;i<n;i++) f[i]=A[i];for (int i=n;i<(1<<l);i++) f[i]=t[i]=0;NTT(f,0);NTT(t,0);for (int i=0;i<(1<<l);i++) B[i]=(ll)t[i]*dec(2,(ll)f[i]*t[i]%MOD)%MOD;NTT(B,1);for (int i=n;i<(1<<l);i++) B[i]=0;
}
inline void deriv(int* A,int* B,int n){for (int i=0;i<n-1;i++) B[i]=(ll)A[i+1]*(i+1)%MOD;B[n-1]=0;}
inline void integ(int* A,int* B,int n){for (int i=1;i<n;i++) B[i]=(ll)A[i-1]*fac[i-1]%MOD*finv[i]%MOD;B[0]=0;}
void getln(int* A,int* B,int n)
{static int f[MAXN],g[MAXN];deriv(A,f,n);getinv(A,g,n);for (int i=n;i<(1<<l);i++) f[i]=g[i]=0;NTT(f,0);NTT(g,0);for (int i=0;i<(1<<l);i++) f[i]=(ll)f[i]*g[i]%MOD;NTT(f,1);integ(f,B,n);for (int i=n;i<(1<<l);i++) B[i]=0;
}
void getexp(int* A,int* B,int n)
{static int f[MAXN],g[MAXN];if (n==1) return (void)(*B=1);getexp(A,g,(n+1)>>1);getln(g,f,n);for (int i=0;i<n;i++) f[i]=dec(A[i],f[i]);++f[0];for (int i=n;i<(1<<l);i++) f[i]=g[i]=0;NTT(f,0);NTT(g,0);for (int i=0;i<(1<<l);i++) B[i]=(ll)f[i]*g[i]%MOD;NTT(B,1);for (int i=n;i<(1<<l);i++) B[i]=0;
}
void getpow(int* A,int* B,int n,int k)
{static int t[MAXN];getln(A,t,n);for (int i=0;i<n;i++) t[i]=(ll)t[i]*k%MOD;getexp(t,B,n);
}
int G[MAXN],H[MAXN],dH[MAXN],A[MAXN],t[MAXN],f[MAXN];
int LangInv(int* F,int n,bool ex=false)
{static int f[MAXN],g[MAXN];for (int i=0;i<n;i++) f[i]=F[i+1];f[n]=0;getinv(f,g,n);getpow(g,f,n,n);int ans=0;if (ex)	for (int i=0;i<n;i++) ans=add(ans,(ll)dH[i]*f[n-i-1]%MOD);else ans=f[n-1];return (ll)ans*fac[n-1]%MOD*finv[n]%MOD;
}
time_t START;
int main()
{fac[0]=1;for (int i=1;i<MAXN;i++) fac[i]=(ll)fac[i-1]*i%MOD;finv[MAXN-1]=inv(fac[MAXN-1]);for (int i=MAXN-2;i>=0;i--) finv[i]=(ll)finv[i+1]*(i+1)%MOD;rt[0][23]=qpow(3,119);rt[1][23]=inv(rt[0][23]);for (int i=22;i>=0;i--){rt[0][i]=(ll)rt[0][i+1]*rt[0][i+1]%MOD;rt[1][i]=(ll)rt[1][i+1]*rt[1][i+1]%MOD;}int n=read();for (int i=0;i<=n;i++) t[i]=(ll)qpow(2,((ll)i*(i-1)/2)%(MOD-1))*finv[i]%MOD;getln(t,G,n+1);for (int i=0;i<=n;i++) G[i]=(ll)G[i]*i%MOD;for (int i=0;i<n;i++) t[i]=G[i+1];t[n]=0;getln(t,H,n+1);deriv(H,dH,n+1);for (int s=read();s;s--){int p=read()-1;A[p]=LangInv(G,p,true);}getexp(A,t,n+1);getinv(t,A,n+1);for (int i=1;i<=n;i++) f[i]=A[i-1];f[0]=0;printf("%d\n",(ll)LangInv(f,n)*fac[n-1]%MOD);return 0;
}

P.S. 如果你用LOJ的C++(NOI) T成了狗,试试C++……

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/315089.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.NET Core on K8S学习初探(1)

“ [LOG] ASP.NET Core on K8S Starting...”01—写在之前当近期的一个App上线后&#xff0c;发现目前的docker实例&#xff08;应用服务BFF中台服务工具服务&#xff09;已经越来越多了&#xff0c;而我司目前没有专业的运维人员&#xff0c;发现运维的成本逐渐开始上来&#…

AtCoder Regular Contest 120 C - Swaps 2 线段树模拟

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你两个序列a,ba,ba,b&#xff0c;每次可以执行一个操作&#xff1a;将a[i]a[i]a[i]与a[i1]a[i1]a[i1]交换&#xff0c;且让交换后的a[i]1,a[i1]−1a[i]1,a[i1]-1a[i]1,a[i1]−1&#xff0c;问将aaa变成bbb…

【BZOJ 4671】异或图 【斯特林反演】【线性基】【贝尔数复杂度】

传送门 题意&#xff1a;定义两个图的异或的边集为在两张图中恰出现一次的边。给sss张nnn个点的图的集合&#xff0c;求异或和为连通图的子集数。 s≤60,n≤10s \leq 60,n \leq 10s≤60,n≤10 设GiG_iGi​表示异或出iii个连通块的子集数&#xff0c;答案就是G1G_1G1​ GGG并不…

.NET Core IdentityServer4实战 第Ⅳ章-集成密码登陆模式

回顾下ClientCredentials模式&#xff0c;在ReSourceApi中定义了我们公开服务&#xff0c;第三方网站想要去访问ReSourceApi则需要在身份验证服务中获取toekn&#xff0c;根据token的内容&#xff0c;硬编码去访问公开服务&#xff08;ResApi&#xff09;,这个还是非常简单的&a…

Codeforces Round #656 (Div. 3) F. Removing Leaves 贪心 + 模拟

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 首先有一个贪心策略就是每次都找一个叶子节点最多的点&#xff0c;让后删掉他的kkk个叶子节点&#xff0c;现在我们就来考虑如何模拟这个过程。 我们整一个vector<set<int>>ve…

.NetCore中三种注入生命周期的思考

.NetCore彻底诠释了“万物皆可注入”这句话的含义&#xff0c;在.NetCore中到处可见注入的使用。因此core中也提供了三种注入方式的生命周期使用&#xff0c;分别是&#xff1a;AddTransient&#xff1a;每次请求&#xff0c;都获取一个新的实例。即使同一个请求获取多次也会是…

兰州大学第一届 飞马杯 体育课排队 二分 + 最大流 + 输出路径

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 读懂题就会辣&#xff0c;经典模型了&#xff0c;二分时间&#xff0c;让后将其转换成二分图&#xff0c;左边是人&#xff0c;右边是位置&#xff0c;能在规定时间到的连边&#xff0c;跑…

从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用Application Part动态加载控制器和视图...

如果你使用过一些开源CMS的话&#xff0c;肯定会用过其中的的插件化功能&#xff0c;用户可以通过启用或者上传插件包的方式动态添加一些功能&#xff0c;那么在ASP.NET Core MVC中如何实现插件化开发呢&#xff0c;下面我们来探究一下。本系列只是笔者的一些尝试&#xff0c;并…

感性理解Berlekamp-Massey算法

引入 BM算法主要解决的是根据数列求最短线性齐次递推式的问题在OI中主要辅助打表使用 即&#xff1a;已知FFF&#xff0c;求序列AAA使得 Fn∑i1mAiFn−i(n>m)F_n\sum_{i1}^mA_iF_{n-i} \quad(n>m)Fn​i1∑m​Ai​Fn−i​(n>m) 其中mmm尽量小 算法流程 文中的所有…

兰州大学第一届 飞马杯 ★★飞马祝福语★★ 线段树维护dp(动态dp)

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你一个串&#xff0c;每次将区间都修改为某一个字母&#xff0c;问最终包含多少个FeiMaFeiMaFeiMa子序列。 思路&#xff1a; 首先暴力修改肯定是不行的&#xff0c;复杂度nqnqnq。 如果没有修改操作&am…

兰州大学第一届 飞马杯 ★★快乐苹果树★★ 树链剖分 + 懒标记 + 树状数组

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 第一次听说树链剖分能在fa[top[i]]fa[top[i]]fa[top[i]]的地方加懒标记&#xff0c;学到了学到了。 首先不能被题目吓住&#xff0c;这个题目仔细剖析一下不难发现一些性质&#xff1a; 以…

【BZOJ3328】PYXFIB【矩阵快速幂】【单位根反演】【二项式定理】

传送门 题意&#xff1a; ∑i0⌊nk⌋(nik)Fik\sum_{i0}^{\lfloor\frac nk\rfloor}\binom n{ik}F_{ik}i0∑⌊kn​⌋​(ikn​)Fik​ FFF为斐波拉契数列 n≤1e18,k≤2e4,p≤1e9n\leq 1e18,k\leq2e4,p\leq1e9n≤1e18,k≤2e4,p≤1e9且为质数且模kkk余111 显然就是求 ∑i0n[k∣i](ni…

.NET分布式框架 | Orleans 知多少

引言公司物联网项目集成Orleans以支持高并发的分布式业务&#xff0c;对于Orleans也是第一次接触&#xff0c;本文就分享下个人对Orleans的理解。这里先抛出自己的观点&#xff1a;Orleans 是一个支持有状态云生应用/服务水平伸缩的基于Virtual Actor 模型的.NET分布式框架。下…

nowcoder 牛牛的最大兴趣组 质因子 + 思维

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 首先nnn很小的话可以暴力连边&#xff0c;让后染个色求一个颜色最多的即可。但是这个题显然不行&#xff0c;由于是三次方&#xff0c;所以考虑质因子入手。 首先很容易就能想到将所有的数…

ASP.NET Core on K8S学习初探(3)部署API到K8S

“ 终于可以部署ASP.NET Core到K8S中了...”在上一篇《基本概念快速一览》中&#xff0c;我们把基本的一些概念快速地简单地不求甚解地过了一下&#xff0c;本篇开始我们会将ASP.NET Core WebAPI部署到K8S&#xff0c;从而结束初探的旅程。01—准备一个WebAPI这里准备一个空的A…

K-D Tree学习笔记

引入 K-D Tree 是一种处理高维空间的数据结构。 支持O(nk−1k)O(n^{\frac {k-1}k})O(nkk−1​)查询给定超矩形内的点的信息&#xff0c; kkk 为维数。 可以用替罪羊树的思想实现动态插入。 但其实用的最多的是在错误的复杂度内查询奇奇怪怪的点信息。 构建 K-D Tree 是平…

Codeforces Round #633 B. Edge Weight Assignment 结论题 + dp

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 思路&#xff1a; 首先考虑最小值&#xff0c;如果从一个叶子结点出发到任意叶子的距离都为偶数&#xff0c;那么只需要一个值就可以满足条件。如果有奇数的&#xff0c;考虑111 ^ 222 ^ 303030&#xff0c;…

ASP.NET Core Web API中使用Swagger

本节导航Swagger介绍在ASP.NET CORE 中的使用swagger在软件开发中,管理和测试API是一件重要而富有挑战性的工作。在我之前的文章《研发团队,请管好你的API文档》 也专门阐述了通过文档管理工具,来保证API文档和代码的一致性,这样更加有助于团队的协作。以往我们总是通过第三方平…

【ZJOI2015】幻想乡战略游戏【点分树】【带权重心】

题意&#xff1a;nnn个点带边权的树&#xff0c;动态修改点权viv_ivi​&#xff0c;最小化 钦定一个点xxx 后 ∑idist(x,i)∗vi\sum\limits_{i} dist(x,i)*v_ii∑​dist(x,i)∗vi​的值。 n,q≤105n,q \leq10^5n,q≤105&#xff0c;度数不超过202020 限制度数的树上的一些诡异…

P4559 [JSOI2018]列队 主席树

传送门 文章目录题意&#xff1a;思路&#xff1a;题意&#xff1a; 给你nnn个学生以及其位置&#xff0c;mmm个询问&#xff0c;每次询问[l,r][l,r][l,r]的学生跑到[k,kr−l][k,kr-l][k,kr−l]的位置的最小总的移动距离。当然不同的学生不能站在同一位置。 n,m≤5e5,1≤ai,k≤…