以下考虑直接对所有$F(A)$求和,并给出两种做法——

做法1:

枚举答案$A$,对应方案数为${n-A\choose m}^{2}-{n-A-1\choose m}^{2}$,即答案为$\sum_{i=0}^{n-1}({n-i\choose m}^{2}-{n-i-1\choose m}^{2})F(i)$

记$G(n)=\sum_{i=0}^{n-1}{n-i\choose m}^{2}F(i)$,有$ans=G(n)-G(n-1)$,以下仅考虑求$G(n)$

不难证明$G(n)$是一个关于$n$的不超过$3m+1$次的多项式(将$3m$次多项式求前缀和即为$3m+1$次),更具体的,我们只需要求出$G(0),G(1),...,G(3m+1)$就可以确定$G(n)$

根据拉格朗日差值,维护$o(m)$以内的阶乘即逆元就可以$o(m)$的插出一个位置上的值

接下来,我们考虑怎么求出$G(i)$($0\le i\le 3m+1$):

先考虑求出所有$F(i)$($0\le i\le 3m+1$)的值,单次$o(m)$总复杂度即为$o(m^{2})$,无法通过

考虑拉格朗日插值法具体的式子,即为$F(i)=\sum_{j=0}^{m}F(j)\prod_{0\le k\le m,k\ne j}\frac{i-k}{j-k}$

预处理出$H_{j}=F(j)\prod_{0\le k\le m,k\ne j}\frac{1}{j-k}$,则$F(i)=\sum_{j=0}^{m}H_{j}\prod_{0\le k\le m,k\ne j}(i-k)$

当$0\le i\le m$,直接可得结果,那么假设$m<i\le 3m+1$,则$\prod_{0\le k\le m,k\ne j}(i-k)=\frac{\prod_{0\le k\le m}(i-k)}{i-j}$

简单化简,即$F(i)=\prod_{j=0}^{m}(i-j)\sum_{j=0}^{m}\frac{H_{j}}{i-j}$,前者利用逆元即可以从上一个$o(1)$算出,后者考虑$H_{i}$的生成函数$H(x)=\sum_{i=0}^{m}H_{i}x^{i}$和$H'(x)=\sum_{i=1}^{3m+1}\frac{x^{i}}{i}$,那么即$(H\times H')(x)[x^{i}]$

接下来,对于$G(i)=\sum_{j=0}^{i-1}{i-j\choose m}^{2}F(j)$,考虑$F(j)$的生成函数$F'(x)=\sum_{i=0}^{3m+1}F(i)x^{i}$以及$H''(x)=\sum_{i=1}^{3m+1}{i\choose m}^{2}x^{i}$,有$G(i)=(F'\times H'')(x)[x^{i}]$

用ntt计算多项式乘法,复杂度为$o(m\log m)$

最后$G(n)=\sum_{i=0}^{3m+1}G(i)\prod_{0\le j\le 3m+1,j\ne i}\frac{n-j}{i-j}$,$o(m)$差值即可

但这一做法的常数较大,我写不过去QAQ

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N (1<<23)
4 #define mod 998244353
5 int n,m,t,inv[N],Inv[N],rev[N],a[N],b[N],f[N];
6 int ksm(int n,int m){
7 n=(n+mod)%mod;
8 int s=n,ans=1;
9 while (m){
10 if (m&1)ans=1LL*ans*s%mod;
11 s=1LL*s*s%mod;
12 m>>=1;
13 }
14 return ans;
15 }
16 void ntt(int *a,int p){
17 for(int i=0;i<N;i++)
18 if (i<rev[i])swap(a[i],a[rev[i]]);
19 for(int i=2;i<=N;i<<=1){
20 int s=ksm(3,(mod-1)/i);
21 if (p)s=ksm(s,mod-2);
22 for(int j=0;j<N;j+=i)
23 for(int k=0,ss=1;k<(i>>1);k++,ss=1LL*ss*s%mod){
24 int x=a[j+k],y=1LL*a[j+k+(i>>1)]*ss%mod;
25 a[j+k]=(x+y)%mod;
26 a[j+k+(i>>1)]=(x+mod-y)%mod;
27 }
28 }
29 if (p){
30 int s=ksm(N,mod-2);
31 for(int i=0;i<N;i++)a[i]=1LL*a[i]*s%mod;
32 }
33 }
34 int get(int n){
35 if (n<=t)return f[n];
36 int ss=1,ans=0;
37 for(int i=0;i<=t;i++)ss=1LL*ss*(n-i)%mod;
38 for(int i=0;i<=t;i++){
39 int s=1LL*Inv[t-i]*Inv[i]%mod;
40 if ((t-i)&1)s=mod-s;
41 s=1LL*s*ss%mod*ksm(n-i,mod-2)%mod;
42 ans=(ans+1LL*f[i]*s)%mod;
43 }
44 return ans;
45 }
46 int main(){
47 scanf("%d%d",&n,&m);
48 t=3*m+1;
49 for(int i=0;i<=m;i++)scanf("%d",&f[i]);
50 inv[0]=inv[1]=Inv[0]=1;
51 for(int i=2;i<=t;i++)inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
52 for(int i=1;i<=t;i++)Inv[i]=1LL*Inv[i-1]*inv[i]%mod;
53 for(int i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)+((i&1)*(N>>1));
54 for(int i=0;i<=m;i++){
55 int s=1LL*Inv[m-i]*Inv[i]%mod;
56 if ((m-i)&1)s=mod-s;
57 a[i]=1LL*s*f[i]%mod;
58 }
59 for(int i=1;i<=t;i++)b[i]=inv[i];
60 ntt(a,0);
61 ntt(b,0);
62 for(int i=0;i<N;i++)a[i]=1LL*a[i]*b[i]%mod;
63 ntt(a,1);
64 int s=1;
65 for(int i=1;i<=m;i++)s=1LL*s*i%mod;
66 for(int i=m+1;i<=t;i++){
67 s=1LL*s*inv[i-m-1]%mod*i%mod;
68 f[i]=1LL*a[i]*s%mod;
69 }
70 memset(a,0,sizeof(a));
71 s=1;
72 for(int i=m;i<=t;i++){
73 a[i]=1LL*s*s%mod;
74 s=1LL*s*(i+1)%mod*inv[i-m+1]%mod;
75 }
76 ntt(a,0);
77 ntt(f,0);
78 for(int i=0;i<N;i++)f[i]=1LL*f[i]*a[i]%mod;
79 ntt(f,1);
80 printf("%d",(get(n)-get(n-1)+mod)%mod);
81 }

做法2:

考虑$F(x)=1$的情况,由于$F(A)=1$,答案即为${n\choose m}^{2}$

当然,也可以枚举最终染色的球的数量$k$,对应方案数为${n\choose k}{k\choose m}{m\choose 2m-k}$(最后一个是$m$是因为第二次染色重复只能与第一次重复,内部不能重复),复杂度为$o(m)$

(由于以下还会使用${k\choose m}{m\choose 2m-k}$,将之记作$H_{k}$)

这一做法看上去没有什么意义,但其提示我们具体的位置是不好枚举的,要考虑个数,也就是要让$F(x)$与位置无关(如$F(x)=1$就与位置无关)

考虑$F(x)=x$的情况,构造$A$的组合意义:在两次染色完毕后,再染一个球,且这个球必须是$A$之前的球,那么第三次染色方案数恰好为$A$,三次染色的总方案数即为答案

枚举这三次染色所染的球数量$k+1$,类似的方案数即为${n\choose k+1}H_{k}$

考虑$F(x)=x^{c}$的情况,构造$A^{c}$的组合意义:在两次染色完毕后,再染$c$个球,允许内部重复但同样必须是$A$之前的球的方案数,同样这三次染色的总方案数即为答案

枚举这三次染色所染的球数量$k+t$,前半部分相同为${n\choose k+t}H_{k}$,下面考虑最后$t$个球如何染色

这是一个可以容斥的问题,即枚举强制不能染色的位置个数$i$,即$\sum_{i=0}^{t}(-1)^{i}{t\choose i}(t-i)^{c}$

为了让其可以计算,将组合数展开,即$t!\sum_{i=0}^{t}\frac{(-1)^{i}}{i!}\cdot \frac{(t-i)^{c}}{(t-i)!}$

这又是一个ntt的形式,即$H_{1}(x)=\sum_{i=0}^{m}\frac{(-1)^{i}}{i!}x^{i}$和$H_{2}(x)=\sum_{i=0}^{m}\frac{i^{c}}{i!}x^{i}$,那么$(H_{1}\times H_{2})(x)[x^{i}]$即为$t=i$时除以$t!$的结果,将其乘上$t!$并记作$G_{t}$

之后又是一个$G_{t}$和$H_{k}$的卷积,即$G(x)=\sum_{i=0}^{m}G_{i}x^{i}$以及$H(x)=\sum_{i=m}^{2m}H_{i}x^{i}$,那么$(H\times G)(x)[x^{i}]$即为$k+t=i$时的答案,再乘上${n\choose k+t}$后相加即可

当$F(x)$为普通多项式时,不难发现每一次可以独立,且$H$不变,根据卷积的分配律,可以将所有$G_{i}$相加后做一次,即$G_{i}=\sum_{i=0}^{t}(-1)^{i}{t\choose i}F(t-i)$

类似的构造$H_{2}(x)=\sum_{i=0}^{m}\frac{F(i)}{i!}x^{i}$,求出$G_{i}$后与上面的做法相同

两次ntt即可,时间复杂度为$o(m\log m)$,由于此时多项式次数变为$2m+m$次,常数更小,可以通过

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N (1<<22)
4 #define mod 998244353
5 int n,m,ans,fac[N],inv[N],rev[N],a[N],b[N];
6 int c(int n,int m){
7 if (n<m)return 0;
8 return 1LL*fac[n]*inv[m]%mod*inv[n-m]%mod;
9 }
10 int ksm(int n,int m){
11 n=(n+mod)%mod;
12 int s=n,ans=1;
13 while (m){
14 if (m&1)ans=1LL*ans*s%mod;
15 s=1LL*s*s%mod;
16 m>>=1;
17 }
18 return ans;
19 }
20 void ntt(int *a,int p){
21 for(int i=0;i<N;i++)
22 if (i<rev[i])swap(a[i],a[rev[i]]);
23 for(int i=2;i<=N;i<<=1){
24 int s=ksm(3,(mod-1)/i);
25 if (p)s=ksm(s,mod-2);
26 for(int j=0;j<N;j+=i)
27 for(int k=0,ss=1;k<(i>>1);k++,ss=1LL*ss*s%mod){
28 int x=a[j+k],y=1LL*a[j+k+(i>>1)]*ss%mod;
29 a[j+k]=(x+y)%mod;
30 a[j+k+(i>>1)]=(x+mod-y)%mod;
31 }
32 }
33 if (p){
34 int s=ksm(N,mod-2);
35 for(int i=0;i<N;i++)a[i]=1LL*a[i]*s%mod;
36 }
37 }
38 int main(){
39 scanf("%d%d",&n,&m);
40 for(int i=0;i<=m;i++)scanf("%d",&a[i]);
41 fac[0]=inv[0]=inv[1]=1;
42 for(int i=1;i<=3*m;i++)fac[i]=1LL*fac[i-1]*i%mod;
43 for(int i=2;i<=3*m;i++)inv[i]=1LL*(mod-mod/i)*inv[mod%i]%mod;
44 for(int i=1;i<=3*m;i++)inv[i]=1LL*inv[i-1]*inv[i]%mod;
45 for(int i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)+((i&1)*(N>>1));
46 for(int i=0;i<=m;i++){
47 a[i]=1LL*a[i]*inv[i]%mod;
48 b[i]=inv[i];
49 if (i&1)b[i]=mod-b[i];
50 }
51 ntt(a,0);
52 ntt(b,0);
53 for(int i=0;i<N;i++)a[i]=1LL*a[i]*b[i]%mod;
54 ntt(a,1);
55 memset(b,0,sizeof(b));
56 for(int i=1;i<=2*m;i++){
57 if (i>m)a[i]=0;
58 else a[i]=1LL*fac[i]*a[i]%mod;
59 b[i]=1LL*c(i,m)*c(m,2*m-i)%mod;
60 }
61 ntt(a,0);
62 ntt(b,0);
63 for(int i=0;i<N;i++)a[i]=1LL*a[i]*b[i]%mod;
64 ntt(a,1);
65 int s=1;
66 for(int i=0;i<=3*m;i++){
67 ans=(ans+1LL*a[i]*s%mod*inv[i])%mod;
68 s=1LL*s*(n-i)%mod;
69 }
70 printf("%d",ans);
71 }

[loj2504]小H爱染色的更多相关文章

  1. hihocoder 1347 小h的树上的朋友

    传送门 时间限制:18000ms单点时限:2000ms内存限制:512MB 描述 小h拥有$n$位朋友.每位朋友拥有一个数值$V_i$代表他与小h的亲密度.亲密度有可能发生变化.岁月流逝,小h的朋友们 ...

  2. 【渗透笔记】拿下某小H网的全过程

    自从班上A片小王子的7个T资源被封了以后,本小白为造福全班同学,尝试拿下个小H网,先用webrobot搜某些只有小H网才会出现的关键词 本以为直接导出放御剑里跑就行了,然并软.于是用awvs扫了一下, ...

  3. 一个简洁的小H车调运模型

    一个简洁的小H车调运模型 不久前, 帝都B城市到处都是小H车, 理想的小H车应该是布朗运动\均匀分布,可是现实上它们就是不均匀.于是有如下问题: 观察帝都 HD区SY村区域,将其划分成10个用车点,用 ...

  4. 小H和密码

    链接:https://www.nowcoder.com/acm/contest/72/B来源:牛客网 题目描述     小H在击败怪兽后,被一个密码锁挡住了去路     密码锁由N个转盘组成,编号为1 ...

  5. acdream 1725 哗啦啦的小彭玉染色问题 离散化并查集

    哗啦啦的小彭玉染色问题 Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acdream.info/problem?pid=1725 Descri ...

  6. 【Wannafly挑战赛10 - B】小H和密码(DP)

    试题链接:https://www.nowcoder.com/acm/contest/72/B 题目描述     小H在击败怪兽后,被一个密码锁挡住了去路     密码锁由N个转盘组成,编号为1~N,每 ...

  7. BZOJ1505: [NOI2004]小H的小屋

    BZOJ1505: [NOI2004]小H的小屋 Description 小H发誓要做21世纪最伟大的数学家.他认为,做数学家与做歌星一样,第一步要作好包装,不然本事再大也推不出去. 为此他决定先在自 ...

  8. hihocoder-1347 小h的树上的朋友(lca+线段树)

    题目链接: 小h的树上的朋友 时间限制:18000ms 单点时限:2000ms 内存限制:512MB 描述 小h拥有n位朋友.每位朋友拥有一个数值Vi代表他与小h的亲密度.亲密度有可能发生变化. 岁月 ...

  9. Wannafly挑战赛10:A题:小H和迷宫

    题目描述       小H陷入了一个迷宫中,迷宫里有一个可怕的怪兽,血量有N点,小H有三瓶魔法药水,分别可以使怪兽损失a%.b%.c%的血量(之后怪兽的血量会向下取整),小H想合理地运用这三瓶药水,使 ...

随机推荐

  1. 在Windows Server 2012R2离线安装.net framework3.5

    最近新装了一台Windows Server 2012 R2的服务器,安装数据库时,出现了提示安装不上 .net framework3.5的情况,经过网络上多次的资料查找及反复试验终于找到了一个可以解决 ...

  2. Java泛型中的细节

    Java泛型中的细节 如果没有泛型 学习Java,必不可少的一个过程就是需要掌握泛型.泛型起源于JDK1.5,为什么我们要使用泛型呢?泛型可以使编译器知道一个对象的限定类型是什么,这样编译器就可以在一 ...

  3. Linux 下 SVN 的安装和配置

    SVN 是一个自由开源的版本管理系统,它可以按照时间的顺序去管理文件.目录以及对其进行的修改.于今,它被广泛的用于互联网公司的项目版本管理中 工作原理 它的工作原理如下图所示 它是由一个SVN服务器和 ...

  4. C/C++入门级小游戏——开发备忘录

    很多工科的学生在大一都有一门课程,叫C语言程序设计.大概就是装个IDE然后和一个黑乎乎的窗口打交道,期末到了考完试就结束了.然而很多人可能都有一个疑惑:C语言究竟能干什么?除开嵌入式单片机这些高大上的 ...

  5. Java(5)输入和输出

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201515.html 博客主页:https://www.cnblogs.com/testero ...

  6. XiaoXin 13Pro-Hackintosh 小新13pro崇尚极简的黑苹果双系统

    Lenovo XiaoXin-13-Pro-Hackintosh 关键词:Hackintosh XiaoXin EFI Tutorial Lenovo 以下提及的EFI及其他部分文件见github仓库 ...

  7. 力扣 - 剑指 Offer 53 - I. 在排序数组中查找数字 I

    题目 剑指 Offer 53 - I. 在排序数组中查找数字 I 思路1 一般来说,首先想到的是使用一个变量,从头开始遍历整个数组,记录target数组出现的次数,但是这样的时间复杂度是O(n),还是 ...

  8. Java:并发笔记-07

    Java:并发笔记-07 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 6. 共享模型之不可变 本章内容 不可变类的使用 不可变类设计 无状态类设计 6.1 ...

  9. java监控JVM的内存使用情况等

    以下的程序监控参数的代码,有些是从网络上获取的,此处进行一个记录是为了以后如果要用到方便记录. 1.引入jar包,为了获取一些cpu的使用率等信息 <dependency> <gro ...

  10. CSP2021 翻车记

    DAY - INF 日常模拟赛被吊打,不知道为啥总是出一些小问题导致正解gg,成绩的话也就是中游吧,不过方差不小 DAY - 2 感冒了,头疼得很,签到题甚至也签到失败了,烦得很 DAY -1 全真体 ...