• BZOJ3284 不等式


    不等式

    给定如下不等式组

    [∀1 ≤ i ≤ n, x_i ≤ t\ sum_{i=1}^m x_i ≤ S ]

    给定 (S,t, n, m),求解数。

    • (S ≤ 10^{18})

    • (n ≤ m ≤ 10^9)

    • (t ≤ 10^9,n ⋅ t ≤ S)

    • (m − n ≤ 10^3)

    题解

    仓鼠《杂题选讲》。

    假如暴力枚举前(n)个变量的取值,令它们的和为(X),那么后面的变量方案数可以用组合数算出答案就是 (inom{S−X}{m−n})

    (inom{S−X}{m−n}) 展开成一个关于(x)(m − n)次多项式(F(x))

    那么只要对于每个(0 ≤ k ≤ m − n)(k),均计算出(sum_{∀1≤i≤n,x_i≤t}(x_1 +x_2 + ⋯ + x_n)^k),然后代入到(F(x))里面即可。

    记一个长度为(m − n + 1)的向量(G_l),其中(G_{l,k})表示的就是(sum_{∀1≤i≤l,x_i≤t}(x_1 +x_2 + ⋯ + x_l)^k) ,不难发现由(G_a)(G_b)可以直接(O( (m − n)^2))求出(G_{a+b})。直接倍增算出(G_n)即可。

    时间复杂度 (O((m-n)^2log n))

    CO int N=1e3+10;
    int fac[N],ifac[N];
    
    IN int C(int n,int m){
    	return mul(fac[n],mul(ifac[m],ifac[n-m]));
    }
    int lagrange(int n,int T){
    	static int val[N];
    	for(int i=1;i<=n+2;++i) val[i]=add(val[i-1],fpow(i,n));
    	static int pre[N],suf[N];
    	pre[0]=1;
    	for(int i=1;i<=n+2;++i) pre[i]=mul(pre[i-1],T+mod-i);
    	suf[n+3]=1;
    	for(int i=n+2;i>=1;--i) suf[i]=mul(suf[i+1],T+mod-i);
    	int ans=0;
    	for(int i=1;i<=n+2;++i){
    		int sum=mul(val[i],mul(pre[i-1],suf[i+1]));
    		sum=mul(sum,mul(ifac[i-1],ifac[n+2-i]));
    		ans=add(ans,(n+2-i)%2==0?sum:mod-sum);
    	}
    	return ans;
    }
    poly operator+(CO poly&a,CO poly&b){
    	int n=a.size()-1;
    	poly ans(n+1);
    	for(int i=0;i<=n;++i)for(int j=0;j<=i;++j)
    		ans[i]=add(ans[i],mul(C(i,j),mul(a[j],b[i-j])));
    	return ans;
    }
    poly operator*(CO poly&a,CO poly&b){
    	int n=a.size()-1,m=b.size()-1;
    	poly ans(n+m+1);
    	for(int i=0;i<=n;++i)for(int j=0;j<=m;++j)
    		ans[i+j]=add(ans[i+j],mul(a[i],b[j]));
    	return ans;
    }
    
    int main(){
    	fac[0]=1;
    	for(int i=1;i<N;++i) fac[i]=mul(fac[i-1],i);
    	ifac[N-1]=fpow(fac[N-1],mod-2);
    	for(int i=N-2;i>=0;--i) ifac[i]=mul(ifac[i+1],i+1);
    	
    	int64 S=read<int64>();int T=read<int>();
    	int n=read<int>(),m=read<int>()-n;
    	poly g(m+1);
    	for(int i=0;i<=m;++i) g[i]=lagrange(i,T);
    	poly f(m+1);f[0]=1;
    	for(;n;n>>=1,g=g+g) if(n&1) f=f+g;
    	poly p={1};
    	for(int i=0;i<m;++i) p=p*(poly){int((S-i)%mod),mod-1};
    	int ans=0;
    	for(int i=0;i<=m;++i) ans=add(ans,mul(p[i],f[i]));
    	printf("%d
    ",mul(ans,ifac[m]));
    	return 0;
    }
    
  • 相关阅读:
    PHP格式化时间戳函数分享
    The Mac App Store isn't working. How to fix?
    sqlite+ef+powertools
    部署node api的二三事
    node 写api几个简单的问题
    基于项目的简单的代码生成器
    h5跳转到app的实现
    几种常用的git命令
    发送post请求几种常见content-type类型
    cors(Cross-origin resource sharing)跨域资源共享
  • 原文地址:https://www.cnblogs.com/autoint/p/12557742.html
Copyright © 2020-2023  润新知