• uoj#420. 【集训队作业2018】矩形(组合数学)


    题面

    传送门

    题解

    这辣鸡题目做了咱整整三天……咱果然还是太菜了……好珂怕的推倒啊……

    首先把它变成

    [left( sum_{i = 1}^{n} sum_{j = 1}^{m} F(i, j) \, h^{im + j} ight) mod p]

    那么最后求答案的时候乘上的({1over h^{m+1}})就行了

    我们考虑对(v)(即题目中的(f_i))和(c)分别计算贡献

    (sub_1)

    对于(v_x),打个表可以发现,第(x)行第(1)列它的系数为(b),第(2)列系数为(b^2),以及第(x+i)行第(j)列的系数为({i+j-1choose j-1}a^ib^jh^{(i+x)m}h^j)

    我们对它的系数求和,就是

    [egin{aligned} cnt &=sum_{i=0}^{n-x}a^ih^{(i+x)m}sum_{j=1}^{m}{i+j-1choose j-1}b^{j}h^{j}\ &=bh^{xm+1}sum_{i=0}^{n-x}a^ih^{im}sum_{j=0}^{m-1}{i+jchoose j}b^{j}h^{j}\ end{aligned} ]

    [egin{aligned} f_n=sum_{i=0}^na^ih^{im}sum_{j=0}^{m-1}{i+jchoose j}b^{j}h^{j}\ g_n=sum_{j=0}^{m-1}{n+jchoose j}b^{j}h^{j}\ end{aligned} ]

    于是我们显然可以写出(f_n)的递推式(f_n=f_{n-1}+a^nh^{nm}g_n)

    那么我们只要能搞出(g)就可以求出(f),进而求出每个(v_x)的系数了

    那么继续推倒

    [egin{aligned} g_n &=sum_{j=0}^{m-1}{n+jchoose j}b^{j}h^{j}\ &=sum_{j=0}^{m-1}left({n+j-1choose j-1}+{n-1+jchoose j} ight)b^{j}h^{j}\ &=bhsum_{j=0}^{m-2}{n+jchoose j}b^{j}h^{j}+sum_{j=0}^{m-1}{n-1+jchoose j}b^{j}h^{j}\ &=bhleft(g_n-{n+m-1choose m-1}b^{m-1}h^{m-1} ight)+g_{n-1} end{aligned} ]

    然后就分类讨论啊,如果(bh)等于(1),就消掉(g_n),可以直接得出(g_{n-1})的式子。如果(bh)不等于(1),就移项解方程。于是

    [g_n=egin{cases} {n+mchoose m-1}&bh=1\ {g_{n-1}+{n+m-1choose m-1}b^mh^mover 1-bh}&bh eq 1 end{cases} ]

    初值分别为(m(bh=1))({1-b^mh^mover 1-bh}(bh eq 1))

    然后递推出(g),进而求出(f),对于每个(v_x)乘上(bh^{xm+1})(f_{n-x})就行了

    (sub_2)

    然后我们考虑(c)的贡献

    对于位置((x,y))((i,j)(ileq x,jleq y))上的每一个(c)都会对这一个位置有贡献,我们可以看做向下走一步乘(a),向右走一步乘(b)((x,y))(c)的系数就是从所有((i,j))走到它的所有路径的权值之和。那么这个位置上(c)的系数就是就是

    [F(x,y)=sum_{i=0}^{x-1}sum_{j=0}^{y-1}a^ib^j{i+jchoose j} ]

    总的系数就是

    [sum_{x=1}^nh^{xn}sum_{y=1}^mh^ysum_{i=0}^{x-1}sum_{j=0}^{y-1}a^ib^j{i+jchoose j} ]

    我们记(G(x,y)=h^ysum_{i=0}^{x-1}sum_{j=0}^{y-1}a^ib^j{i+jchoose j})

    和上面一样化简。

    [egin{aligned} G(x,y) &=h^ysum_{i=0}^{x-1}sum_{j=0}^{y-1}a^ib^jleft({i+j-1choose j-1}+{i-1+jchoose j} ight)\ &=h^yasum_{i=0}^{x-2}sum_{j=0}^{y-1}a^ib^j{i+jchoose j}+h^ybsum_{i=0}^{x-1}sum_{j=0}^{y-2}a^ib^j{i+jchoose j}+h^y end{aligned} ]

    注意,中间把组合数拆开来的时候,这个式子对({0choose 0})实际上是不适用的,所以我们少算了({0choose 0})的贡献,所以最后要加上(h^y)(咱因为没发现这个细节卡了好久)

    继续推倒

    [G(x,y)=aG(x-1,y)+bleft(G(x,y)-hsum_{i=0}^{x-1}a^ib^{y-1}h^{y-1}{i+y-1choose y-1} ight)+h^y ]

    我们对这个东西求一个和,也就是记(T(x)=sum_{y=1}^m G(x,y)),有

    [T(x)=aT(x-1)+bleft(T(x)-hsum_{i=0}^{x-1}a^isum_{j=0}^{m-1}b^jh^j{i+jchoose j} ight)+{h(1-h^m)over 1-h} ]

    虽然最后的(h^y)的求和还要特判一下(h=1)的情况不过想必大家都是明白的我就不写了

    中间那一大坨是什么东西啊……回过头去看看……

    (sum_{j=0}^{m-1}b^jh^j{i+jchoose j})不等于(g_i)么……

    [T(x)=aT(x-1)+bleft(T(x)-hsum_{i=0}^{x-1}a^ig_i ight)+{h(1-h^m)over 1-h} ]

    还是分类讨论,如果(b=1)我们可以直接求出(T(x-1))的通项公式,否则就可以解出(T(x))的递推公式

    然后枚举(x),每一个(x)都要让系数加上(h^{xm}T(x)),最后系数乘上(c)就行了

    搞清楚字母哪个是哪个,别跟咱一样连自己写的啥都不知道了……

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define ll long long
    #define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
    #define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=1e6+15;
    int v[N],f[N],g[N],d[N],inv[N],t[N];
    int n,m,h,P,a,b,c,res,x,y;
    inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
    inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
    inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
    int ksm(R int x,R ll y){
    	R int res=1;
    	for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
    	return res;
    }
    int calc1(){
    	int res=0,tmp;
    	if(mul(b,h)==1){
    		f[0]=g[0]=tmp=m;
    		fp(i,1,n){
    			tmp=1ll*(i+m)%P*tmp%P*inv[i+1]%P;
    			g[i]=tmp;
    		}
    	}else{
    		int p=mul(b,h),q=ksm(p,m);
    		p=ksm(dec(1,p),P-2);
    		tmp=1,f[0]=g[0]=mul(dec(1,q),p);
    		fp(i,1,n){
    			tmp=1ll*(i+m-1)%P*tmp%P*inv[i]%P;
    			g[i]=dec(g[i-1],mul(tmp,q)),g[i]=mul(g[i],p);
    		}
    	}
    	int p=1,k=mul(a,ksm(h,m));
    	fp(i,1,n)p=mul(p,k),f[i]=add(f[i-1],mul(p,g[i]));
    	int x=mul(b,h),y=ksm(h,m);
    	fp(i,1,n)x=mul(x,y),res=add(res,1ll*x*f[n-i]%P*v[i]%P);
    	return res;
    }
    int calc2(){
    	int res=0,qwq=(h==1)?m%P:1ll*h*dec(1,ksm(h,m))%P*ksm(dec(1,h),P-2)%P;
    	if(b==1){
    		int tmp=g[0],k=1,inva=ksm(a,P-2);
    		fp(i,1,n)k=mul(k,a),tmp=add(tmp,mul(k,g[i])),t[i]=mul(dec(1ll*tmp*h%P*b%P,qwq),inva);
    	}else{
    		int tmp=g[0],k=1,invb=ksm(dec(1,b),P-2);
    		fp(i,1,n){
    			t[i]=mul(a,t[i-1]);
    			t[i]=dec(t[i],1ll*b*h%P*tmp%P);
    			t[i]=add(t[i],qwq);
    			t[i]=mul(t[i],invb);
    			k=mul(k,a),tmp=add(tmp,mul(k,g[i]));
    		}
    	}
    	int g=1,k=ksm(h,m);
    	fp(i,1,n)g=mul(g,k),res=add(res,mul(g,t[i]));
    	return mul(res,c);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	read(),n=read(),m=read(),h=read(),P=read(),a=read(),b=read(),c=read();
    	if(!h)return printf("%d
    ",add(c,mul(b,read()))),0;
    	inv[0]=inv[1]=1;fp(i,2,n+5)inv[i]=mul(P-P/i,inv[P%i]);
    	fp(i,1,n)v[i]=read();
    	x=calc1(),y=calc2();
    	res=ksm(h,m+1),res=ksm(res,P-2),res=mul(res,add(x,y));
    	printf("%d
    ",res);
    	return 0;
    }
    
  • 相关阅读:
    INFORMATION_SCHEMA.COLUMNS表的字段信息
    如何取得一个数据表的所有列名
    CASE 函数
    Js定制窗口
    获取当前数据库中的所有用户表
    Js让状态栏不显示链接地址
    RA病人关节残障与软骨破坏而非骨破坏相关
    抗阿达木单抗的抗体可能与阿达木单抗治疗过程中静脉和动脉血栓事件相关
    长期应用阿达木单抗时所产生的抗抗体会影响疗效
    多普勒超声预测抗TNFα治疗类风湿关节炎患者的有效性:一项前瞻性队列研究
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10466783.html
Copyright © 2020-2023  润新知