虽然标算是生成函数,但是我们只要头够铁就能用矩阵对角化日过去的

如果我们知道了有几个颜色出现了奇数次,我们就能够计算出这个方案合不合法

所以直接大力dp(i)表示有i个颜色出现了奇数次的方案数就行了

显然转移可以矩阵乘法,但是矩阵似乎非常奇怪,是主对角线的两侧分布着1~n和n~1的系数矩阵

众所周知,计算一个向量乘杨辉三角的逆矩阵和普通的杨辉三角的结果

都是可以使用ntt在\(O(nlogn)\)的时间内完成计算的

现在我们希望强行将这个矩阵对角化,事实证明这是可行的

(我不是很清楚有什么办法可以手推出对角矩阵来……这个对角矩阵是我瞎试出来的)

首先通过高斯消元法我们可以解出来这个n+1矩阵的特征值分别是\(2^0,2^1,\dots 2^n\)

紧接着我们带进去反解出特征向量,发现特征向量半点规律都没有

本着出题人不会瞎造矩阵,就算瞎造了矩阵自然法则也不会让我们难受的原则,

我们将特征向量有序的排列得到一个有序的矩阵

仔细观察会发现这个矩阵等于杨辉三角倒置之后再乘2再乘杨辉三角的逆矩阵

然后使用ntt模拟矩阵乘法即可

#include<cstdio>
#include<algorithm>
using namespace std;const int N=262144+10;typedef long long ll;const ll mod=998244353;
inline ll po(ll a,ll p){ll r=1;for(;p;p>>=1,a=a*a%mod)if(p&1)r=r*a%mod;return r;}
int rv[22][N];ll rt[2][22];ll fac[N];ll ifac[N];ll tw[N];
int D;int n;int m;ll a[N];ll f[N];ll g[N];
# define md(x) (x=(x>=mod)?x-mod:x)
inline void ntt(ll* a,int len,int d,int o)
{for(int i=1;i<len;i++)if(i<rv[d][i])swap(a[i],a[rv[d][i]]);for(int k=1,j=1;k<len;k<<=1,j++)for(int s=0;s<len;s+=(k<<1))for(int i=s,w=1;i<s+k;i++,w=w*rt[o][j]%mod){ll a1=a[i+k]*w%mod;a[i+k]=a[i]+mod-a1;md(a[i+k]);a[i]=a[i]+a1;md(a[i]);}ll iv=po(len,mod-2);if(o){for(int i=0;i<len;i++)(a[i]*=iv)%=mod;}
}
inline void pre()
{for(int d=1;d<=18;d++)for(int i=1;i<(1<<d);i++)rv[d][i]=(rv[d][i>>1]>>1)|((i&1)<<(d-1));for(int t=(mod-1)>>1,i=1;i<=20;i++,t>>=1)rt[0][i]=po(3,t);for(int t=(mod-1)>>1,i=1;i<=20;i++,t>>=1)rt[1][i]=po(332748118,t);fac[0]=1;for(int i=1;i<N;i++)fac[i]=fac[i-1]*i%mod;ifac[0]=ifac[1]=1;for(int i=2;i<N;i++)ifac[i]=(mod-mod/i)*ifac[mod%i]%mod;for(int i=1;i<N;i++)(ifac[i]*=ifac[i-1])%=mod;tw[0]=1;for(int i=1;i<N;i++)(tw[i]=tw[i-1]*2)%=mod;
}inline void multrcb(ll* a,int n,int len,int d)
{for(int i=0;i<n;i++)(a[i]*=fac[D-i])%=mod;ntt(a,len<<1,d+1,0);for(int i=0;i<(len<<1);i++)(a[i]*=f[i])%=mod;ntt(a,len<<1,d+1,1);reverse(a,a+n);for(int i=n;i<(len<<1);i++)a[i]=0;for(int i=0;i<n;i++)(a[i]*=ifac[i])%=mod;
}
inline void multicb(ll* a,int n,int len,int d)
{for(int i=0;i<n;i++)(a[i]*=fac[i])%=mod;for(int i=1;i<n;i+=2)a[i]=(mod-a[i])%mod;ntt(a,len<<1,d+1,0);for(int i=0;i<(len<<1);i++)(a[i]*=g[i])%=mod;ntt(a,len<<1,d+1,1);for(int i=0;i<n;i++)a[i]=a[i+D];for(int i=n;i<(len<<1);i++)a[i]=0;for(int i=1;i<n;i+=2)(a[i]=mod-a[i])%=mod;for(int i=0;i<n;i++)(a[i]*=ifac[i])%=mod;
}
int main()
{pre();scanf("%d%d%d",&D,&n,&m);int lim=n-2*m;if(lim<0){printf("0\n");return 0;}if(lim>=D){printf("%lld",po(D,n));return 0;}int len=1;int d=0;for(;len<=D;len<<=1,d++);for(int i=0;i<=D;i++)f[i]=ifac[i];for(int i=0;i<=D;i++)g[D-i]=ifac[i];ntt(f,len<<1,d+1,0);ntt(g,len<<1,d+1,0);a[0]=1;multicb(a,D+1,len,d);for(int i=0;i<=D;i++)(a[i]*=tw[i])%=mod;multrcb(a,D+1,len,d);for(int i=0;i<=D;i++)(a[i]*=po((D+mod-2*i)%mod,n))%=mod;multicb(a,D+1,len,d);for(int i=0;i<=D;i++)(a[i]*=tw[i])%=mod;multrcb(a,D+1,len,d);ll ans=0;ll iv=po(po(2,D),mod-2);for(int i=0;i<=D;i++)(a[i]*=iv)%=mod;for(int i=0;i<=lim;i++)(ans+=a[i])%=mod;printf("%lld",ans%mod);return 0;
}

转载于:https://www.cnblogs.com/sweetphoenix/p/11054999.html

#3120. 「CTS2019 | CTSC2019」珍珠相关推荐

  1. Loj #3124. 「CTS2019 | CTSC2019」氪金手游

    Loj #3124. 「CTS2019 | CTSC2019」氪金手游 题目描述 小刘同学是一个喜欢氪金手游的男孩子. 他最近迷上了一个新游戏,游戏的内容就是不断地抽卡.现在已知: - 卡池里总共有 ...

  2. 「CTS2019 | CTSC2019」氪金手游 解题报告

    「CTS2019 | CTSC2019」氪金手游 降 智 好 题 ... 考场上签到失败了,没想容斥就只打了20分暴力... 考虑一个事情,你抽中一个度为0的点,相当于把这个点删掉了(当然你也只能抽中 ...

  3. 【LOJ】#3123. 「CTS2019 | CTSC2019」重复

    LOJ3123 60pts 正难则反,熟练转成总方案数减掉每个片段都大于等于s的字典序的方案 按照一般的套路建出kmp上每个点加一个字符的转移边的图(注意这个图开始字母必须是nxt链中下一个相邻的字符 ...

  4. LOJ#3124. 「CTS2019 | CTSC2019」氪金手游 容斥+DP

    神仙容斥+DP可还行. code: #include <cstdio> #include <cmath> #include <vector> #include &l ...

  5. #loj3124. 「CTS2019 | CTSC2019」氪金手游

    简单容斥 先假设所有点的权值都给定了 随便选一个点当根开始dfs,如果所有边都是向下指的那么答案就是 \[\prod_{u}\frac{w(u)}{siz(u)}\] 其中\(siz(u)\)表示u子 ...

  6. LOJ 3124 「CTS2019 | CTSC2019」氪金手游——概率+树形DP

    题目:https://loj.ac/problem/3124 看了题解:https://www.cnblogs.com/Itst/p/10883880.html 先考虑外向树. 考虑分母是 \( \s ...

  7. 「CTS2019」氪金手游

    「CTS2019」氪金手游 解题思路 考场上想出了外向树的做法,居然没意识到反向边可以容斥,其实外向树会做的话这个题差不多就做完了. 令 \(dp[u][i]\) 表示单独考虑 \(u\) 节点所在子 ...

  8. 噢,我这该死的魅力,国潮新锐品牌「二某某」她来了她来了

    做工厂做产品的人不浪漫?人称「彭老师」的彭伊朵并不同意,彭伊朵毕业于北师大,曾是中学语文老师,深耕制造业数十年后毅然创立「二某某」,成为品牌创始人.彭伊朵与她的团队深谙产品的结构原理.生产流程及外观设 ...

  9. loj2058 「TJOI / HEOI2016」求和 NTT

    loj2058 「TJOI / HEOI2016」求和 NTT 链接 loj 思路 \[S(i,j)=\frac{1}{j!}\sum\limits_{k=0}^{j}(-1)^{k}C_{j}^{k ...

最新文章

  1. HTML 常用标签全称
  2. python Selenium 常见操作 元素定位
  3. python能处理多大的数据-Python 适合大数据量的处理吗?
  4. Redis命令:DECR key减1操作
  5. centos7.4 U盘安装卡在 starting dracut initqueue hook
  6. SpringBoot_入门-课程简介
  7. 【MySQL】Mysql索引优化与底层数据结构深入剖析 - 笔记
  8. ASP.Net请求处理机制初步探索之旅 - Part 1 前奏
  9. JavaScript中的const
  10. 系统集成资质-信息系统项目管理师考试综合介绍
  11. 黑板课爬虫闯关之关卡二
  12. StreamInsight 浅入浅出(三)—— 适配器
  13. Ansible Tower:安装以及HA多集群安装
  14. 博图注册表删除方法_回收站删除的文件怎么恢复?手把手教你找回
  15. 中航信Eterm协议解析,解包,封包源码
  16. uniapp选择图片压缩并上传
  17. 免费企业邮箱: Google企业邮箱的申请
  18. 地球上最长的两座山脉:一座4800公里,一座8900公里
  19. SANGFOR深信服远程办公客户端EasyConnect在Windows11使用兼容性问题解决案例
  20. 小游戏系列算法之五广度优先搜索,双向广搜,八数码,华容道

热门文章

  1. java oo 封装_javaOO——封装、static、成员内部类
  2. nodejs集成sqlite
  3. salt-api安装与配置
  4. 11.排序算法_1_快速排序
  5. Swift变量名的一种玩法
  6. Java记录 -45- List的toString方法
  7. sqlserver实验心得体会_SQLServer数据库实训总结
  8. centos7 安装java 8_CentOS 7.8下安装完美安装配置Rosetta
  9. Bootstrap自适应居中问题
  10. 开放防火墙/26ip段_在5个不同国家/地区采用开放硬件设计的电子产品