传送门

好久没写题解了,就过来水两篇。

对于每一个人,考虑一个序列$A$,$A_I$表示当k取值为 i 时的答案。

如果说有两个人,我们可以把$(A+B)^k$二项式展开,这样就发现把两个人合并起来的操作就是一次卷积,直接NTT就可以了。

同类人有多个,直接暴力肯定是不行的。快速幂的话不知道会不会T,我是用了多项式取ln和exp(拉板子)。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MN 400002
using namespace std;
int read_p,read_ca;
inline int read(){
read_p=;read_ca=getchar();
while(read_ca<''||read_ca>'') read_ca=getchar();
while(read_ca>=''&&read_ca<='') read_p=read_p*+read_ca-,read_ca=getchar();
return read_p;
}
const int MOD=,g=;
inline int mi(int x,int y){
int mmh=;
while (y){
if (y&) mmh=1LL*mmh*x%MOD;
y>>=;x=1LL*x*x%MOD;
}
return mmh;
}
int tot,k,n,m,f[MN],mmh,I[MN],_I[MN],L[MN],R[MN],MMH,N[MN],A[MN],B[MN],e[MN],_e[MN],W[MN],C_a[MN],C_b[MN],N_c[MN],C[MN],D[MN],Q[MN],_A[MN],_B[MN],ANS[MN];
inline void M(int &x){while(x>=MOD)x-=MOD;while(x<)x+=MOD;}
inline int ask(int n,int k){
for (int i=;i<=k+;i++) N[i]=mi(i,k);
for (int i=;i<=k+;i++) M(N[i]+=N[i-]);
n%=MOD;
for (int i=;i<=k+;i++) L[i]=R[i]=n-i;
for (int i=;i<=k+;i++) L[i]=1ll*L[i-]*L[i]%MOD;
for (int i=k;i>=;i--) R[i]=1ll*R[i+]*R[i]%MOD;
mmh=;
for (int i=;i<=k+;i++){
MMH=N[i];
if (i>) MMH=1LL*MMH*_I[i]%MOD*L[i-]%MOD;
if (i<k+) MMH=1LL*MMH*_I[k+-i]%MOD*((k+-i)%?-:)*R[i+]%MOD;
M(mmh+=MMH);
}
return mmh;
}
inline void inv(){
int base=mi(g,(MOD-)/tot),_base=mi(base,MOD-);
e[]=_e[]=;
for (int i=;i<=tot;i++) e[i]=1LL*e[i-]*base%MOD,_e[i]=1LL*_e[i-]*_base%MOD;
}
inline void NTT(int N,int a[],int w[]){
for (int j,i=j=;i<N;i++){
if (i>j) swap(a[i],a[j]);
for (int k=N>>;(j^=k)<k;k>>=);
}
for (int i=;i<=N;i<<=){
for (int k,j=k=,s=tot/i;k<(i>>);j+=s,k++) W[k]=w[j];
for (int m=i>>,j=;j<N;j+=i)
for (int k=;k<m;k++){
int A=j+k,B=A+m,z=1LL*a[B]*W[k]%MOD;
M(a[B]=a[A]-z);
M(a[A]+=z);
}
}
}
inline void cc(int n,int m,int a[],int b[],int c[]){
int N=,i;while (N<(n+m)) N<<=;
for (i=;i<n;i++) C_a[i]=a[i];fill(C_a+n,C_a+N,);
for (i=;i<m;i++) C_b[i]=b[i];fill(C_b+m,C_b+N,);
NTT(N,C_a,e);NTT(N,C_b,e);
for (i=;i<N;i++) c[i]=1LL*C_a[i]*C_b[i]%MOD;
NTT(N,c,_e);
int w=mi(N,MOD-);
for (i=;i<N;i++) c[i]=1LL*c[i]*w%MOD;
}
inline void _D(int n,int a[],int b[]){for (int i=;i<n;i++) b[i]=1LL*(i+)*a[i+]%MOD;b[n]=;}
inline void _S(int n,int a[],int b[]){for (int i=n;i;i--) b[i]=1LL*a[i-]*I[i]%MOD;b[]=;}
void ny(int n,int a[],int b[]){
if (n==) memset(b,,sizeof(int)*tot),b[]=mi(a[],MOD-);else{
ny((n+)>>,a,b);
register int i;
int N=;while (N<(n<<)) N<<=;
copy(a,a+n,N_c);fill(N_c+n,N_c+N,);
NTT(N,N_c,e);NTT(N,b,e);
for (i=;i<N;i++) b[i]=(2LL-1LL*N_c[i]*b[i]%MOD+MOD)*b[i]%MOD;
NTT(N,b,_e);
int w=mi(N,MOD-);
for (i=;i<n;i++) b[i]=1LL*b[i]*w%MOD;fill(b+n,b+N,);
}
}
void sqrt(int n,int a[],int b[]){
if (n==) memset(b,,sizeof(int)*tot),b[]=int(sqrt(a[])+0.5);else{
sqrt((n+)>>,a,b);
register int i;
int N=,w=I[];while (N<(n<<)) N<<=;
copy(b,b+n,D);fill(D+n,D+N,);
for (i=;i<n;i++) M(D[i]<<=);
ny(n,D,C);
cc(n,n,a,C,C);
for (i=;i<n;i++) b[i]=(1LL*w*b[i]+C[i])%MOD;
}
}
inline void Ln(int n,int a[],int b[]){
memset(C,,sizeof(int)*tot);memset(D,,sizeof(int)*tot);
_D(n,a,D);ny(n,a,C);
cc(n,n,D,C,b);
_S(n,b,b);
}
void exp(int n,int a[],int b[]){
if (n==) memset(b,,sizeof(int)*tot),b[]=;else{
exp((n+)>>,a,b);
Ln(n,b,Q);
int N=,w=(MOD+)>>;while (N<(n<<)) N<<=;
for (int i=;i<n;i++) M(Q[i]=a[i]-Q[i]);M(Q[]+=);
cc(n,n,Q,b,b);
fill(b+n,b+N,);
}
}
void work(int n,int C[]){
if (n==){
C[]=;
for (int i=;i<k;i++) C[i]=;
}
for (int i=;i<k;i++) A[i]=_I[i+];
ny(k,A,B);
for (int i=;i<k;i++) A[i]=1LL*mi(n+,i+)*_I[i+]%MOD;
cc(k,k,A,B,C);
}
int main(){
scanf("%d%d%d",&k,&m,&n);k++;
for(tot=;tot<(k<<);tot<<=);inv();
I[]=;for (int i=;i<MN;i++) I[i]=1LL*(MOD-MOD/i)*I[MOD%i]%MOD;
f[]=_I[]=;for (int i=;i<MN;i++) _I[i]=1LL*_I[i-]*I[i]%MOD,f[i]=1LL*f[i-]*i%MOD;
//scanf("%d%d%d",&k,&m,&n);
//n=3;k=10;
/*for (int i=0;i<=k;i++) S[i]=1LL*ask(n,i)*I[i]%MOD;
for (int i=0;i<=k;i++){
int o=0;
for (int j=0;j<=i;j++) o=(1LL*S[i]*I[j+1]+o)%MOD;
printf("%d ",o);
}
puts("");
for (int i=0;i<=k;i++)
printf("%d ",1LL*(mi(n+1,i+1)-1)*I[i+1]%MOD);
puts("");
*/
ANS[]=;
for (int i=;i<=n;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
work(a-,_A);work(b,_B);
//for (int i=0;i<k;i++) printf("%d ",1ll*_B[i]*f[i]%MOD);puts("");
int tmp=mi(b-a+,MOD-);
for (int i=;i<k;i++) M(_B[i]-=_A[i]),_B[i]=1LL*_B[i]*tmp%MOD;
Ln(k,_B,_A);
for (int i=;i<k;i++) _A[i]=1LL*_A[i]*c%MOD;
exp(k,_A,_B);
cc(k,k,ANS,_B,ANS);
//for (int i=0;i<k;i++) printf("%d ",1LL*ANS[i]*f[i]);puts("");
}
printf("%d\n",1LL*ANS[k-]*f[k-]%MOD);
}

Codechef July Challenge 2018 : Picking Fruit for Chefs的更多相关文章

  1. Codechef July Challenge 2018 : Subway Ride

    传送门 首先(想了很久之后)注意到一个性质:同一条边有多种颜色的话保留3种就可以了,这是因为假如最优解要求当前位置与相邻两条边都不相同,那么只要有3条边,就肯定可以满足这一点. 完事就做一个nlogn ...

  2. Codechef October Challenge 2018 游记

    Codechef October Challenge 2018 游记 CHSERVE - Chef and Serves 题目大意: 乒乓球比赛中,双方每累计得两分就会交换一次发球权. 不过,大厨和小 ...

  3. Codechef September Challenge 2018 游记

    Codechef September Challenge 2018 游记 Magician versus Chef 题目大意: 有一排\(n(n\le10^5)\)个格子,一开始硬币在第\(x\)个格 ...

  4. codechef February Challenge 2018 简要题解

    比赛链接:https://www.codechef.com/FEB18,题面和提交记录是公开的,这里就不再贴了 Chef And His Characters 模拟题 Chef And The Pat ...

  5. Codechef STMINCUT S-T Mincut (CodeChef May Challenge 2018) kruskal

    原文链接http://www.cnblogs.com/zhouzhendong/p/9010945.html 题目传送门 - Codechef STMINCUT 题意 在一个有边权的无向图中,我们定义 ...

  6. Codechef August Challenge 2018 : Chef at the River

    传送门 (要是没有tjm(Sakits)的帮忙,我还真不知道啥时候能做出来 结论是第一次带走尽可能少的动物,使未带走的动物不冲突,带走的这个数量就是最优解. 首先这个数量肯定是下界,更少的话连第一次都 ...

  7. Codechef August Challenge 2018 : Safe Partition

    传送门 (虽然是A了但是不知道复杂度是不是正确的 考虑以某个位置为结尾的合法划分 先考虑min,带来的影响是限制了最小长度,预处理出这个最小长度后,这可以在处理到这个数时,把不能算的部分去掉(不满足m ...

  8. Codechef August Challenge 2018 : Interactive Matrix

    传送门 首先整个矩阵可以被分为很多小矩阵,小矩阵内所有行的单调性是一样的,所有列的单调性是一样的. 考虑如何在这样一个小矩阵中找出答案.我的策略是每次取四个角中最大值和最小值的点,这样可以每次删掉一行 ...

  9. Codechef August Challenge 2018 : Lonely Cycles

    传送门 几波树形dp就行了. #include<cstdio> #include<cstring> #include<algorithm> #define MN 5 ...

随机推荐

  1. EF CodeFirst系列(8)--- FluentApi配置单个实体

    我们已经知道了在OnModelCreating()方法中可以通过FluentApi对所有的实体类进行配置,然而当实体类很多时,我们把所有的配置都放在OnModelCreating()方法中很难维护.E ...

  2. 第一节:从面向对象思想(oo)开发、接口、抽象类以及二者比较

    一. 面向对象思想 1. 面向过程(OP)和面向对象(OO)的区别: (1):面向过程就是排着用最简单的代码一步一步写下去,没有封装,当业务复杂的时候,改动就很麻烦了 (2):面向对象将复杂的业务分离 ...

  3. oldboy s21day11

    #!/usr/bin/env python# -*- coding:utf-8 -*- # 1.列举 str.list.dict.set 中的常用方法(每种至少5个),并标注是否有返回值.'''str ...

  4. css样式关键字(initial,inherit,unset,revert,all)

    关键字 在CSS中,有4个关键字理论上可以应用于任何的CSS属性,它们是initial(初始).inherit(继承).unset(未设置).revert(还原).而all的取值只能是以上这4个关键字 ...

  5. Generator和Coroutine学习

    简单的生产者消费者模型 #!/usr/bin/python2.7 def consumer(): while True: newn = yield print 'Consumer : {}'.form ...

  6. [物理学与PDEs]第3章第2节 磁流体力学方程组 2.2 考虑到电磁场的存在对流体力学方程组的修正

    1.  连续性方程 $$\bex \cfrac{\p \rho}{\p t}+\Div(\rho{\bf u})=0.  \eex$$ 2.  动量守恒方程 $$\bex \cfrac{\p }{\p ...

  7. Java之final关键字详解

    1. 修饰类 当用final去修饰一个类的时候,表示这个类不能被继承. 注意: a. 被final修饰的类,final类中的成员变量可以根据自己的实际需要设计为fianl. b. final类中的成员 ...

  8. mysql常见的问题

    1.为什么选择某一个版本 各个版本之间的区别及优缺点 首先,服务器特性 mysql percona mysql mariaDB 开源 开源 开源 支持分区表 支持分区表 支持分区表 innodb Xt ...

  9. Python中__get__, __getattr__, __getattribute__的区别及延迟初始化

    本节知识点 1.__get__, __getattr__, __getattribute__的区别 2.__getattr__巧妙应用 3.延迟初始化(lazy property) 1.__get__ ...

  10. XSS闯关游戏准备阶段及XSS构造方法

    请下载好XSS闯关文件后,解压后放在服务器的对应文件夹即可 在该闯关中,会在网页提示一个payload数值 payload,翻译过来是有效载荷 通常在传输数据时,为了使数据传输更可靠,要把原始数据分批 ...