[JZOJ5364]史莱姆
来源:互联网 发布:程序员很闲 编辑:程序博客网 时间:2024/04/28 10:58
题目大意
给你一个棱长为
一次攻击定义为:你对一个棱长为
两种方案不同定义为:存在一对棱长为1的正方体单位x,y,在一种方案中他们属于同一个正方体而另一种方案他们属于不同正方体。
多组数据。
T≤100000,n≤40,m≤30000。
分析
一个小DP:
设f[i][j][k]表示考虑到大小为
很显然
这就是部分分了。
这东西没办法优化了,我们要换个思路。
看到统计方案的题,想想生成函数总是没问题的,首先要推出一个能够搞生成函数的dp。
我们反过来,合成一个
设f[i][j]表示一个
现在我们把f(i)看成一个多项式,f[i][j]表示f[i]的第j项的系数,就可以FFT了!
这个NTT有大半年没打···低级错误犯了好多,回顾一下。
len为原多项式次数界之和,再调整到2^x。
递归过程中:对n次多项式带入
我们DFT的过程中,求
对t[i]分析,分组转化得
括号里的东西分别储存在
二进制表示的下标中,a为dft目标数组,t为过程数组,
dft后,两个数组相乘,所有的点值都要乘,不然插值会出错。
插值就把
预处理原根下的那些主次方根。
代码
#include<cstdio>#include<algorithm>#include<cmath>#include<cstring>#include<set>using namespace std;#define fo(i,j,k) for(i=j;i<=k;i++)#define fd(i,j,k) for(i=j;i>=k;i--)typedef long long ll;typedef double db;const int N=1e5+5,mo=998244353,rt=3;int Log,w[N],len,n,m,T,i,f[42][N],g[N],a[N],invl,j,k;int t[N];struct rec{ int n,m,id;}b[N];int ksm(int x,int y){ int ret=1; while (y) { if (y&1) ret=1ll*ret*x%mo; y>>=1; x=1ll*x*x%mo; } return ret;}int mx2(int x){ int ret=1;Log=0; while (ret<x) ret*=2,Log++; return ret;}void predo(){ int i; w[0]=1; w[1]=ksm(rt,(mo-1)/len); fo(i,2,len) w[i]=1ll*w[i-1]*w[1]%mo;}void DFT(int *a,int n,int sig){ int i,j,ws,half,siz,k,pos,u,v; fo(i,0,n-1) { int tp=0; fo(j,0,Log-1) tp=(tp<<1)+(((1<<j)&i)!=0); t[tp]=a[i]; } for(ws=1,siz=2;siz<=n;siz*=2,ws++) { half=siz>>1; fo(i,0,half-1) { for(j=i;j<n;j+=siz) { k=j+half; pos=len/siz*i*sig; if (pos<0) pos+=len; u=t[j];v=1ll*t[k]*w[pos]%mo; t[j]=(u+v)%mo; t[k]=(u-v+mo)%mo; } } } fo(i,0,n-1) a[i]=t[i];}int main(){ scanf("%d\n",&T); fo(i,1,T) { scanf("%d %d",&b[i].n,&b[i].m); n=max(n,b[i].n); m=max(m,b[i].m); b[i].id=i; } f[0][0]=1; len=mx2(m*2+2); invl=ksm(len,mo-2); predo(); fo(i,1,n) { fo(j,0,m) g[j]=f[i-1][j]; fo(j,1,3) { fo(k,0,m) a[k]=g[k]; DFT(a,len,1); fo(k,0,len-1) a[k]=1ll*a[k]*a[k]%mo; DFT(a,len,-1); fo(k,0,m) g[k]=1ll*a[k]*invl%mo; fo(k,0,len-1) a[k]=0; } fo(j,1,m) f[i][j]=g[j-1]; f[i][0]=1; } fo(i,1,T) printf("%d\n",f[b[i].n][b[i].m]);}
- [JZOJ5364]史莱姆
- 【游戏】萌娘の冒险II - 杯具の史莱姆
- 格莱姆.奥波利:平民英雄
- 普莱姆最小生成树算法
- C#莱姆达表达式的使用
- 普莱姆算法生成最小代价树---java代码
- BT之父布莱姆·科恩:极客的莫扎特之梦
- BT之父——Bram Cohen 布莱姆·科亨 简历
- 史
- 名车史
- 计算机病毒史
- 犹太史
- 民国史
- 中华民国史
- 人工智能史
- 装机史
- 计算机语言史
- 英国史
- 算法分析与复杂性理论 第一次上机 2的幂次方表示
- Qt Creator的常用快捷键
- QNX USB device与host模式下驱动脚本详解
- Spring事务回滚
- 剑指offer 练习1
- [JZOJ5364]史莱姆
- NIO详解
- 操作系统复习要点
- 网易2017春招[编程题]堆砖块@Java
- 栗子
- HashMap实现原理及源码分析
- Redis 发布订阅
- 委托_匿名方法
- IntelliJ IDEA(2017)安装和破解,谢谢lanyus