传送门

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

对于每一个人,考虑一个序列$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. NOI-OJ 1.7 ID:21 单词替换

    整体思路 本题如果使用scanf每次读入一个单词.比对替换后再进行输出的话就十分简单,使用这种方法必须要用数组把读入的所有单词存起来,读入的count个单词的前n-2个是原文,第n-1个是查找的单词, ...

  2. CSS+HTML+JQuery实现条形图

    在工作中遇到了写条形图的情况,因为文字,条形数量和条形图的颜色需要改变,所以不能用图片,所以决定写一个试试,写的比较简单,但毕竟是第一次,也遇到了一些问题,特意记录下来,以免忘记. 因为该页面还需要兼 ...

  3. error while loading shared libraries: libg2o_core.so: cannot open shared object file: No such file or directory解决方法

    在build文件夹目录环境下输入: sudo ldconfig 然后编译就可以了.因为g2o刚装,没生效.

  4. Ubuntu里设置python默认版本为python3(转载)

    0 - 步骤 在命令行中执行下述命令: sudo update-alternatives --install /usr/bin/python python /usr/bin/python2 sudo ...

  5. Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC

    解决Invalid character found in the request target. The valid characters are defined in RFC 7230 and RF ...

  6. Jenkins ubantu15 安装使用教程

    Jenkins  ubantu15 安装使用教程 环境:unbatu15 + java version "1.8.0_181"  +   jenkins (2.137) 命令拉取: ...

  7. Flask+Nginx+Supervisor+Gunicorn+HTTPS部署教程(CentOs)

    写在前面 之前的文章中,我们详细讲述了怎样安装 Nginx,Python,Supervisor,Gunicorn,HTTPS.经本人多次测试是完全可以跑通的,那么本篇将介绍怎样将这些组合起来运行一个H ...

  8. JsRender练习总结

    1.假设的数据,基础部分. <div id="list1"></div> <script type="text/tmp" id=& ...

  9. Mac新系统常用设置

    一.MAC OS整个系统的隐藏文件显示可见,在终端下输入以下命令defaults write com.apple.finder AppleShowAllFiles -bool true 二. 在MAC ...

  10. 10分钟理解JS引擎的执行机制

    首先,请牢记2点: (1) JS是单线程语言 (2) JS的Event Loop是JS的执行机制.深入了解JS的执行,就等于深入了解JS里的event loop 1.灵魂三问 (1) JS为什么是单线 ...