zoukankan      html  css  js  c++  java
  • BZOJ5339: [TJOI2018]教科书般的亵渎

    BZOJ5339: [TJOI2018]教科书般的亵渎

    https://lydsy.com/JudgeOnline/problem.php?id=5339

    分析:

    • 难点在于模拟。
    • 除去模拟的部分,我们需要计算(sumlimits_{i=1}^ni^k)
    • 那这显然是关于(n)的一个(k+2)次多项式。
    • 暴力高斯消元(O(k^3))即可,每次求值(O(k))
    • 但这题需要计算(k^2)次,因此总时间复杂度和多数题解一样,都是(O(k^3))

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    using namespace std;
    typedef long long ll;
    #define N 60
    #define mod 1000000007
    ll n,a[N],A[N][N],F[N];
    int m,K;
    ll qp(ll x,ll y) {
    	ll re=1; for(;y;y>>=1,x=x*x%mod) if(y&1) re=re*x%mod; return re;
    }
    inline void upd(ll &x,ll y) {
    	x+=y; if(x>=mod) x-=mod;
    }
    ll S(ll n) {
    	if(n==0) return 0;
    	int i;
    	n=n%mod;
    	ll re=0,now=1;
    	for(i=0;i<=K+1;i++) {
    		re=(re+now*F[i+1])%mod;
    		now=now*n%mod;
    	}
    	return re;
    }
    void Gauss(int n) {
    	int i,j,k;
    	for(i=1;i<=n;i++) {
    		for(j=i;j<=n&&!A[j][i];j++) ;
    		if(j>n) continue;
    		if(i!=j) {
    			for(k=i;k<=n+1;k++) swap(A[i][k],A[j][k]);
    		}
    		ll del=qp(A[i][i],mod-2);
    		for(j=i;j<=n+1;j++) A[i][j]=A[i][j]*del%mod;
    		for(j=1;j<=n;j++) if(j!=i) {
    			del=A[j][i];
    			for(k=i;k<=n+1;k++) {
    				A[j][k]=(A[j][k]-del*A[i][k])%mod;
    			}
    		}
    	}
    }
    void solve() {
    	memset(A,0,sizeof(A));
    	scanf("%lld%d",&n,&m);
    	int i,j;
    	for(i=1;i<=m;i++) scanf("%lld",&a[i]);
    	sort(a+1,a+m+1);
    	m=unique(a+1,a+m+1)-a-1;
    	for(i=m;i;i--) {
    		if(a[i]==n) n--,m--;
    		else break;
    	}
    	ll now,sum;
    	K=m+1;
    	
    	for(i=1;i<=K+2;i++) {
    		now=1,sum=0;
    		for(j=1;j<=i;j++) sum=(sum+qp(j,K))%mod;
    		for(j=1;j<=K+2;j++) {
    			A[i][j]=now;
    			now=now*i%mod;
    		}
    		A[i][K+3]=sum;
    	}
    	Gauss(K+2);
    	for(i=1;i<=K+2;i++) F[i]=A[i][K+3];
    	
    	now=0;
    	ll ans=0; a[m+1]=n+1;
    	for(i=0;i<=m;i++) {
    		for(j=i;j<=m;j++) {
    			ans=(ans+S(a[j+1]-1)-S(a[j]))%mod;
    		}
    		now=a[i+1]-a[i];
    		for(j=i+1;j<=m+1;j++) a[j]-=now;
    	}
    	printf("%lld
    ",(ans%mod+mod)%mod);
    }
    int main() {
    	int T;
    	scanf("%d",&T);
    	while(T--) solve();
    }
    
  • 相关阅读:
    每日作业报告
    每日作业报告
    每日作业报告
    每日作业报告
    每日作业报告
    vue路由跳转错误:Error: Redirected when going from "/login" to "/home" via a navigation guard.
    ubuntu20安装.net core SDK
    SpringBoot启动报错:Failed to configure a DataSource: 'url' attribute is not specified and no embedded
    ubuntu18.04安装rap2
    用例图基本用法
  • 原文地址:https://www.cnblogs.com/suika/p/10229808.html
Copyright © 2011-2022 走看看