正题

题目链接:https://loj.ac/p/6503


题目大意

nnn张卡mmm种,第iii种卡有aia_iai​张,求所有排列中有kkk对相邻且相同的卡牌。

1≤n≤105,0≤k≤105,1≤m≤20000,∑i=1mai=n1\leq n\leq 10^5,0\leq k\leq 10^5,1\leq m\leq 20000,\sum_{i=1}^ma_i=n1≤n≤105,0≤k≤105,1≤m≤20000,∑i=1m​ai​=n


解题思路

kkk对相邻的相同,就是可以分成有n−kn-kn−k组相同的。

考虑这个问题,把每组牌分成若干组插到不同位置,先不考虑这样可能插到相邻位置的情况我们后面可以再用容斥消掉。

那么对于一个aaa,分成iii组的方案就是(a−1i−1)\binom{a-1}{i-1}(i−1a−1​),因为排列,列出生成函数∑i=1a(a−1i−1)xii!\sum_{i=1}^a\binom{a-1}{i-1}\frac{x^i}{i!}∑i=1a​(i−1a−1​)i!xi​。

然后用分治NTTNTTNTT乘起来,最后第iii项乘上一个i!i!i!就是方案了。

然后考虑容斥,枚举一个i≤n−ki\leq n-ki≤n−k然后相当于至少有kkk对相邻,现在要减去更多的,所以容斥系数就是(−1)n−k−i(n−ik)(-1)^{n-k-i}\binom{n-i}{k}(−1)n−k−i(kn−i​)

时间复杂度O(nlog⁡nlog⁡m)O(n\log n\log m)O(nlognlogm)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=2e5+10,T=19,P=998244353;
struct Poly{ll a[N<<2],n;
}F[T+1];bool v[T+1];
ll m,n,k,w[N],inv[N],fac[N],r[N],x[N],y[N];
ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans;
}
void NTT(ll *f,ll n,ll op){for(ll i=0;i<n;i++)if(i<r[i])swap(f[i],f[r[i]]);for(ll p=2;p<=n;p<<=1){ll len=p>>1,tmp=power(3,(P-1)/p);if(op==-1)tmp=power(tmp,P-2);for(ll k=0;k<n;k+=p){ll buf=1;for(ll i=k;i<k+len;i++){ll tt=buf*f[i+len]%P;f[i+len]=(f[i]-tt+P)%P;f[i]=(f[i]+tt)%P;buf=buf*tmp%P;}}}if(op==-1){ll invn=power(n,P-2);for(ll i=0;i<n;i++)f[i]=f[i]*invn%P;}return;
}
void Mul(Poly &F,Poly &G){ll n=1;while(n<F.n+G.n-1)n<<=1;for(ll i=0;i<F.n;i++)x[i]=F.a[i];for(ll i=0;i<G.n;i++)y[i]=G.a[i];for(ll i=F.n;i<n;i++)x[i]=0;for(ll i=G.n;i<n;i++)y[i]=0;for(ll i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)?(n>>1):0);NTT(x,n,1);NTT(y,n,1);for(ll i=0;i<n;i++)x[i]=x[i]*y[i]%P;NTT(x,n,-1);for(ll i=0;i<n;i++)F.a[i]=x[i];F.n=F.n+G.n-1;return;
}
ll FindA(){for(ll i=0;i<T;i++)if(!v[i]){v[i]=1;return i;}
}
ll C(ll n,ll m)
{return fac[n]*inv[m]%P*inv[n-m]%P;}
ll NTT(ll l,ll r){if(l==r){ll x=FindA();for(ll i=1;i<=w[l];i++)F[x].a[i]=inv[i]*C(w[l]-1,i-1)%P;F[x].n=w[l]+1;return x;}ll mid=(l+r)>>1;ll ls=NTT(l,mid),rs=NTT(mid+1,r);Mul(F[ls],F[rs]);v[rs]=0;return ls;
}
signed main()
{scanf("%lld%lld%lld",&m,&n,&k);inv[1]=1;for(ll i=2;i<N;i++)inv[i]=P-inv[P%i]*(P/i)%P;fac[0]=inv[0]=1;for(ll i=1;i<N;i++)fac[i]=fac[i-1]*i%P,inv[i]=inv[i-1]*inv[i]%P;for(ll i=1;i<=m;i++)scanf("%lld",&w[i]);ll p=NTT(1,m),ans=0;for(ll i=n-k,f=1;i>=m;i--,f=-f)ans=(ans+f*F[p].a[i]*fac[i]%P*C(n-i,k)%P)%P;printf("%lld\n",(ans+P)%P);return 0;
}

Loj#6503-「雅礼集训 2018 Day4」Magic【分治NTT】相关推荐

  1. Loj #6503. 「雅礼集训 2018 Day4」Magic

    Loj #6503. 「雅礼集训 2018 Day4」Magic 题目描述 前进!前进!不择手段地前进!--托马斯 · 维德 魔法纪元元年. 1453 年 5 月 3 日 16 时,高维碎片接触地球. ...

  2. Loj 6036 「雅礼集训 2017 Day4」编码 - 2-sat

    题目传送门 唯一的传送门 题目大意 给定$n$个串,每个串只包含 '0','1','?' ,其中 '?' 至多在每个串中出现1次,它可以被替换为 '0' 或 '1' .问是否可能任意两个不同的串不满足 ...

  3. [LOJ]#6515. 「雅礼集训 2018 Day10」贪玩蓝月

    Solution 离线做法很简单,就是线段树分治,不过复杂度是 q m o d log ⁡ qmod\log qmodlog. 考虑在线做法,在线段树分治中,我们并没有利用到删除以及加入都只会在两端进 ...

  4. [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相(树的重心+贪心)

    [LOJ 6042]「雅礼集训 2017 Day7」跳蚤王国的宰相 description solution 一个到所有节点距离和最小的节点 ⇔\Leftrightarrow⇔ 树的重心(满足最重的儿 ...

  5. LibreOJ 6514. 「雅礼集训 2018 Day10」文明【虚树+LCA】

    6514. 「雅礼集训 2018 Day10」文明 [题目描述] 传送门 [题解] 考虑笨蛋的写法,可以用LCA求出1号和其他点的中点,然后DFS搜索Size大小即可,但是,复杂度显然要炸,但是我们会 ...

  6. loj #6046. 「雅礼集训 2017 Day8」爷

    #6046. 「雅礼集训 2017 Day8」爷 题目描述 如果你对山口丁和 G&P 没有兴趣,可以无视题目背景,因为你估计看不懂 -- 在第 63 回战车道全国高中生大赛中,军神西住美穗带领 ...

  7. 「雅礼集训 2018 Day2」农民

    传送门 Description 「搞 OI 不如种田.」 小 D 在家种了一棵二叉树,第 ii 个结点的权值为 \(a_i\). 小 D 为自己种的树买了肥料,每天给树施肥. 可是几天后,小 D 却发 ...

  8. LOJ#6044. 「雅礼集训 2017 Day8」共(Prufer序列)

    题面 传送门 题解 答案就是\(S(n-k,k)\times {n-1\choose k-1}\) 其中\(S(n,m)\)表示左边\(n\)个点,右边\(m\)个点的完全二分图的生成树个数,它的值为 ...

  9. LOJ#6048. 「雅礼集训 2017 Day10」数列(线段树)

    题面 传送门 题解 我的做法似乎非常复杂啊-- 首先最长上升子序列长度就等于把它反过来再接到前面求一遍,比方说把\(2134\)变成\(43122134\),实际上变化之后的求一个最长上升子序列和方案 ...

最新文章

  1. Vivado不同版本打开IP核锁定的解决办法
  2. 进程和线程的关系与区别
  3. vuex 存储刷新_vuex 存储数据 页面刷新不缓存
  4. easyui数据表格显示复选框_【Excel技巧】使用控件一键切换实现单位元和万元随意显示...
  5. bzoj 3994 约数个数和 —— 反演+数论分块
  6. 数据挖掘之自然语言处理
  7. 滴滴否认上海团队解散;雄安超前布局 5G;小米拆分独立品牌 | 极客头条
  8. php xdebug调试 phpstorm配置
  9. Jade win10 安装教程
  10. 华三OSPF多区域配置实例
  11. 牛客面试必刷101代码总结【python】
  12. 远程文件下载/小电影下载
  13. Linux内核4.4 init,linux4.4内核启动到INIT: version 2.88 booting 卡住
  14. vue遇到ie兼容问题如何处理_Vue 2.0 解决IE浏览器的兼容性
  15. HTTPS是如何保证安全的
  16. 基于Arduino uno单片机的仿生螃蟹制作
  17. 20230105无剩余飞行时间的时间制导律:当导弹位于静止目标右侧时就打不中目标?
  18. PT与PX,em(%)区别
  19. SDUT OJ 蟠桃记
  20. MYSQL_精讲数据库数据类型

热门文章

  1. java 数组长度 可变_java基础之集合长度可变的实现原理
  2. python小甲鱼爬虫妹子_【Python学习日记】B站小甲鱼:爬虫
  3. java 推送数据给js,Node.js实现数据推送
  4. c语言 随时启停程序 按钮,单片机C语言控制单按钮启停程序(高手请进)
  5. c语言配电自动化,我是电气工程及其自动化专业的要学C语言吗?
  6. 卡屏java_Java drawImage到屏幕上一卡一卡的
  7. 拆分路径 java_JAVA 类文件中的路径如何拆分和替换
  8. python编_python编
  9. 81. 搜索旋转排序数组 II(014)二分查找+思路+详解+二种做法
  10. 10分钟带你探索css中更为奇妙的奥秘