「2017 山东一轮集训 Day5」苹果树「建议收藏」

「2017 山东一轮集训 Day5」苹果树「建议收藏」「2017 山东一轮集训 Day5」苹果树

大家好,又见面了,我是你们的朋友全栈君。

「2017 山东一轮集训 Day5」苹果

img

\(n\leq 40\)
折半搜索+矩阵树定理。

没有想到折半搜索。

首先我们先枚举\(k\)个好点,我们让它们一定没有用的。要满足这个条件就要使它只能和坏点相连。其他的点没有要求。这样算出来了至少\(k\)个点没有用的生成树个数,我们要得到恰好\(k\)个点的生成树个数就简单容斥一下就好了。

然后我们要得到有\(k\)个点没有用的情况下的点集的方案数。看到\(40\)这个范围我们容易想到折半搜索。

然后就没了。

但是我没写容斥,写的枚举集合划分(被吊打

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 45

using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}

const ll mod=1e9+7;
int n;
ll lim;
int a[N];
ll c[N][N];
ll fac[N],ifac[N],g[N];
ll w[N][N];
ll sum;
ll ksm(ll t,ll x) {
    ll ans=1;
    for(;x;x>>=1,t=t*t%mod)
        if(x&1) ans=ans*t%mod;
    return ans;
}

ll f[N];
ll ned;
int good[N];
ll bad;
int num[N];
ll ans;
ll Gauss(ll a[][45],int n) {
    ll ans=1;
    for(int i=2;i<=n;i++) {
        for(int j=i+1;j<=n;j++) {
            if(a[j][i]) {
                ans=ans*(mod-1)%mod;
                swap(a[i],a[j]);
                break;
            }
        }
        if(!a[i][i]) return 0;
        ans=ans*a[i][i]%mod;
        for(int j=i+1;j<=n;j++) {
            if(!a[j][i]) continue ;
            ll tem=ksm(a[i][i],mod-2)*a[j][i]%mod;
            for(int k=i;k<=n;k++) a[j][k]=(a[j][k]-tem*a[i][k]%mod+mod)%mod;
        }
    }
    return ans;
}

vector<int>st;
ll cal() {
    if(!f[num[1]]) return 0;
    int tot=bad;
    st.clear();
    for(int i=1;i<=n;i++) for(int j=1;j<=num[i];j++) st.push_back(i);
    for(int i=1;i<=n;i++) tot+=num[i];
    memset(w,0,sizeof(w));
        
    for(int i=0;i<st.size();i++) {
        w[i+1][i+1]=st[i]*bad;
        for(int j=st.size()+1;j<=tot;j++) {
            w[i+1][j]=mod-st[i];
        }
    }
    for(int i=st.size()+1;i<=tot;i++) {
        w[i][i]=n-1;
        for(int j=st.size()+1;j<=tot;j++)
            if(i!=j) w[i][j]=mod-1;
        for(int j=0;j<st.size();j++)
            w[i][j+1]=mod-st[j];
    }
    
    ll ans=f[num[1]];
    ans=ans*fac[n-bad-num[1]]%mod%mod;
    for(int i=2;i<=n;i++) {
        ans=ans*ksm(ifac[i],num[i])%mod;
        ans=ans*ksm(g[i],num[i])%mod;
        ans=ans*ifac[num[i]]%mod;
    }
    
    ll tem=Gauss(w,tot);
    return ans*tem%mod;
}

int mid;
void dfs(int v,int lim,ll now,int cnt,vector<int>*a) {
    if(v>lim) return ;
    dfs(v+1,lim,now,cnt,a);
    a[cnt+1].push_back(now+good[v]);
    dfs(v+1,lim,now+good[v],cnt+1,a);
}

void meet_in_the_middle() {
    mid=good[0]>>1;
    vector<int>a[N],b[N];
    dfs(1,mid,0,0,a);
    dfs(mid+1,good[0],0,0,b);
    for(int i=1;i<=mid;i++) sort(a[i].begin(),a[i].end());
    for(int i=1;i<=mid;i++)
        for(int j=0;j<a[i].size();j++)
            if(a[i][j]>=ned) f[i]++;
    for(int i=1;i<=good[0]-mid;i++) {
        for(int j=0;j<b[i].size();j++) {
            if(b[i][j]>=ned) f[i]++;
            for(int k=1;k<=mid;k++) {
                (f[i+k]+=a[k].end()-lower_bound(a[k].begin(),a[k].end(),ned-b[i][j]))%=mod;
            }
        }
    }
}

int dep;
void dfs(int v,int res) {
    if(!res) {
        dep++;
        (ans+=cal())%=mod;
        return ;
    }
    if(!v) return ;
    dfs(v-1,res);
    for(int i=1;i*v<=res;i++) {
        num[v]=i;
        dfs(v-1,res-i*v);
        num[v]=0;
    }
}

bool cmp(int a,int b) {return a>b;}

int main() {
    n=Get(),lim=Get();
    fac[0]=1;
    for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
    ifac[n]=ksm(fac[n],mod-2);
    for(int i=n-1;i>=0;i--) ifac[i]=ifac[i+1]*(i+1)%mod;
    for(int i=0;i<=n;i++)
        for(int j=0;j<=i;j++)
            c[i][j]=(!j||i==j)?1:(c[i-1][j-1]+c[i-1][j])%mod;
            
    for(int i=1;i<=n;i++) a[i]=Get();
    
    for(int i=1;i<=n;i++) {
        if(a[i]>0) {
            good[++good[0]]=a[i];
            sum+=a[i];
        } else bad++;
    }
    ned=sum-lim;
    
    if(sum<=lim) {
        cout<<ksm(n,n-2)%mod;
        return 0;
    }
    if(!bad) {cout<<0;return 0;}
    
    sort(good+1,good+good[0]+1,cmp);
    meet_in_the_middle();
    g[0]=g[1]=1;
    for(int i=2;i<=n;i++) g[i]=ksm(i,i-2)%mod;
    dfs(good[0],good[0]);
    cout<<ans;
    return 0;
}

转载于:https://www.cnblogs.com/hchhch233/p/10470992.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/106955.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Java三大版本「建议收藏」

    Java三大版本「建议收藏」Java三大版本​ Java三大版本代表着Java技术的三个应用领域:JavaSE、JavaME、JavaEE。​ Java以前很长一段时间被称为Java2,所以现在很多人习惯称为J2SE、J2ME、J2EE,它们表示的含义是一样的。JavaSE​ JavaSE,它是JAVA的标准版,是整个JAVA的基础和核心,也是JavaEE和JavaME技术的基础,主要用于开发桌面应用程序。JavaME​ JavaME,它叫做Java的微缩版,主要应用于嵌入式开发,比如手机程序的开发。JavaEE

    2022年7月8日
    19
  • python表白代码,照片隐藏表白话语

    python表白代码,照片隐藏表白话语最近天气好冷,感觉整个人都是冰冰的!程序员如何用python“表白”自己的女神呢?一、具体过程1、代码思路先用cv2中的imread方法读取冰冰的照片,再用PIL的Image方法创建一个相同大小的图像(初始填充白色),最后在图片上每一个块加字。2、python完整代码#-*-coding:utf-8-*-fromPILimportImage,ImageDraw,ImageFontimp

    2022年5月5日
    91
  • 关于cortex-M3/M4中Bit-banding的笔记

    关于cortex-M3/M4中Bit-banding的笔记Bit-bandingBit-bandingmapsacompletewordofmemoryontoasinglebitinthebit-bandregion.Forexample,writingtooneofthealiaswordswillsetorclearthecorrespondingbitinthebitbandre

    2022年10月13日
    3
  • 网络传真的安装及使用方法「建议收藏」

    网络传真的安装及使用方法「建议收藏」在宽带网迅速普及的今天,Modem好像已经“廉颇老矣”,传真Modem已变成了一块“食之无味,弃之可惜”的鸡肋。而且windows的传真模块,已经远远无法满足今天人们快节奏的工作效率。在国外已经非常普遍的网络传真(efax),终于来到了国内,从2004年的引进到根据国内人们使用习惯的不断改进,近10年来,已拥有了百万级的客户群体,特别是近年来,传真营销被企业广泛应用,带来了越来越多的垃圾传

    2022年6月28日
    49
  • AutoEventWireup

    AutoEventWireup
      Google了一番,大家讨论AutoEventWireup问题可不少,Page指令的AutoEventWireup属性被设置为true(或者如果缺少此属性,因为它默认为true),该页框架将自动调用页事件,即Page_Init、Page_Load等14个方法,在这种情况下,不需要任何显式的Handles子句或委托。但这是怎么实现的呢?.net又怎样根据AutoEventWireup属性来动态编译或者预编译页面呢?我在Google上没有找到答案。
     

    2022年5月28日
    35
  • windows10 pycharm2022.01激活【中文破解版】2022.01.27

    (windows10 pycharm2022.01激活)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlGTRPTN90LV-eyJsaWNlbnNlSW…

    2022年3月31日
    139

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号