洛谷P5219 无聊的水题 I [prufer序列,生成函数,NTT]
思路
有标号无根树的计数,还和度数有关,显然可以想到prufer序列。
问题就等价于求长度为\(n-2\),值域为\([1,n]\),出现次数最多的恰好出现\(m-1\)次,这样的序列有哪些。
恰好\(m-1\)次不好求,变成最多\(m-1\)减去最多\(m-2\)的方案数。
考虑指数型生成函数。设要求的最多为\(M\),则设\(A(x)=\sum_{i=0}^M \frac{1}{i!}x^i\),答案就为\((n-2)![x^{n-2}]A^n(x)\),多项式快速幂即可。
代码
#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define templ template<typename T>
#define sz 202020
#define mod 998244353ll
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templ inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
inline void print(register int x)
{
if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
void file()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
}
inline void chktime()
{
#ifndef ONLINE_JUDGE
cout<<(clock()-t)/1000.0<<'\n';
#endif
}
#ifdef mod
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
ll inv(ll x){return ksm(x,mod-2);}
#else
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
#endif
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std;
int n,m;
ll fac[sz],_fac[sz];
void init(){fac[0]=_fac[0]=1;rep(i,1,sz-1) _fac[i]=inv(fac[i]=fac[i-1]*i%mod);}
namespace SOLVE
{
int limit,r[sz];
void NTT_init(int n)
{
int l=-1;limit=1;
while (limit<=n+n) ++l,limit<<=1;
rep(i,0,limit-1) r[i]=(r[i>>1]>>1)|((i&1)<<l);
}
void NTT(ll *a,int type)
{
rep(i,0,limit-1) if (i<r[i]) swap(a[i],a[r[i]]);
for (int mid=1;mid<limit;mid<<=1)
{
ll Wn=ksm(3,(mod-1)/mid>>1);if (type==-1) Wn=inv(Wn);
for (int len=mid<<1,j=0;j<limit;j+=len)
{
ll w=1;
for (int k=0;k<mid;k++,w=w*Wn%mod)
{
ll x=a[j+k],y=w*a[j+k+mid]%mod;
a[j+k]=(x+y)%mod,a[j+k+mid]=(x-y+mod)%mod;
}
}
}
if (type==1) return;
ll I=inv(limit);
rep(i,0,limit-1) a[i]=a[i]*I%mod;
}
ll _a[sz],_b[sz];
void mul(ll *a,ll *b,int n) // a*=b (mod x^n)
{
NTT_init(n);
rep(i,0,n-1) _a[i]=a[i],_b[i]=b[i];
rep(i,n,limit-1) _a[i]=_b[i]=0;
NTT(_a,1);NTT(_b,1);
rep(i,0,limit-1) _a[i]=_a[i]*_b[i]%mod;
NTT(_a,-1);
rep(i,0,n-1) a[i]=_a[i];
}
ll a[sz],b[sz];
ll solve(int m)
{
rep(i,0,n) a[i]=b[i]=0;
rep(i,0,m-1) a[i]=_fac[i];
b[0]=1;
int t=n;
for (;t;t>>=1,mul(a,a,n)) if (t&1) mul(b,a,n);
return fac[n-2]*b[n-2]%mod;
}
}
using SOLVE::solve;
int main()
{
file();
read(n,m);
init();
cout<<(solve(m)-solve(m-1)+mod)%mod;
}
洛谷P5219 无聊的水题 I [prufer序列,生成函数,NTT]的更多相关文章
- 【洛谷】CYJian的水题大赛 解题报告
点此进入比赛 \(T1\):八百标兵奔北坡 这应该是一道较水的送分题吧. 理论上来说,正解应该是DP.但是,.前缀和优化暴力就能过. 放上我比赛时打的暴力代码吧(\(hl666\)大佬说这种做法的均摊 ...
- 【洛谷】CYJian的水题大赛【第二弹】解题报告
点此进入比赛 T1: JerryC Loves Driving 第一题应该就是一道水分题(然而我只水了130分),我的主要做法就是暴力模拟,再做一些小小的优化(蠢得我自己都不想说了). My Code ...
- 洛谷 1082 同余方程——exgcd(水题)
题目:https://www.luogu.org/problemnew/show/P1082 大水题. #include<iostream> #include<cstdio> ...
- 洛谷 P1311 选择客栈 —— 水题
题目:https://www.luogu.org/problemnew/show/P1311 看每个位置能否成为咖啡店,然后作为客栈和前面配对即可. 代码如下: #include<iostrea ...
- 洛谷 P1313 计算系数 —— 水题
题目:https://www.luogu.org/problemnew/show/P1313 不就是...C(k,n) * an * bm . 代码如下: #include<iostream&g ...
- 洛谷 P1969 积木大赛 —— 水题
题目:https://www.luogu.org/problemnew/show/P1969 看每个高度和前面的关系即可. 代码如下: #include<iostream> #includ ...
- 【洛谷2791】 幼儿园篮球题 第二类斯特林数+NTT
求 \(\sum_{i=0}^{k}\binom{m}{i}\binom{n-m}{k-i}i^L\) \((1\leqslant n,m\leqslant 2\times 10^7,1\leqsla ...
- 洛谷 P1223 排队接水
洛谷 P1223 排队接水 题目描述 有n个人在一个水龙头前排队接水,假如每个人接水的时间为Ti,请编程找出这n个人排队的一种顺序,使得n个人的平均等待时间最小. 输入输出格式 输入格式: 输入文件共 ...
- 【洛谷2791】幼儿园篮球题(第二类斯特林数,NTT)
[洛谷2791]幼儿园篮球题(第二类斯特林数,NTT) 题面 洛谷 题解 对于每一组询问,要求的东西本质上就是: \[\sum_{i=0}^{k}{m\choose i}{n-m\choose k-i ...
随机推荐
- treap基本操作
利用rand保持堆的特性 const int N=; int ls[N],rs[N],v[N],p[N],cnt[N],siz[N]; // 权值 优先级 inline void update(int ...
- Eclipse下生成/编辑Java类图或时序图(UML)[转载]
一 引用文章 1.[eclipse下生成Java类图和时序图,生成UML图(更完整版)](https://blog.csdn.net/guomainet309/article/details/5302 ...
- [C++]四分树(Quadtrees)
[本博文非博主原创,思路与题目均摘自 刘汝佳<算法竞赛与入门经典(第2版)>] 四分树Quadtrees 一幅图有1024个点, 可以对图平均分成4块, 并且子图也可以再往下分, 直到一个 ...
- 修改输入框placeholder的样式
1. h5页面: //修改placeholder 样式 (chrome,其余类似加前缀) ::-webkit-input-placeholder { color:rgba(21,30,38,0.35) ...
- luogu P3726 [AH2017/HNOI2017]抛硬币
传送门 我是真的弱,看题解都写了半天,,, 这题答案应该是\(\sum_{i=1}^{a}\binom{a}{i}\sum_{j=0}^{min(b,i-1)}\binom{b}{j}\) 上面那个式 ...
- json 的类型
json靠双引号与单引号, 区分是NUMBER 还是 STRING
- 2016 alictf Timer writeup
Timer-smali逆向 参考文档:http://blog.csdn.net/qq_29343201/article/details/51649962 题目链接: https://pan.baidu ...
- Javascript - ExtJs - Window组件
1.所有组件都可以放入window,此时子组件不需要配置renderTo,只需要将它们作为window的items子项即可. 2.items子项必须先创建,最后创建window,否则子项不会显示. 3 ...
- apache基础学习
1,apache是什么? 目前最主流的三个Web服务器是Apache Nginx IIS 2,环境搭建 linux系统安装xampp: 先下载xampp for linux,放在/opt文件夹下,程序 ...
- Hadoop Steaming开发之WordCount
简单的WordCount栗子--类似于编程语言中的hello world 1.shell脚本run.sh HADOOP_CMD="/usr/local/src/hadoop-1.2.1/bi ...