51nod1446 限制价值树
有N个点(N<=40)标记为0,1,2,...N-1,每个点i有个价值val[i],如果val[i]=-1那么这个点被定义为bad,否则如果val[i] >=0那么这个点为定义为good。现在给这N个点间连上N-1条边,使它们构成一个生成树,定义树中的点为great点当且仅当这个点本身是good点且与其相邻的点中至少有另一个good点。树的价值等于树中所有great点的价值和。定义限制价值树是指价值不大于maxVal的树,问对给定的val[]与maxVal,一共有多少种不同的限制价格树?由于答案太大,可取
modulo 1,000,000,007后的结果。
说明:两棵树是不同的,指两棵树的边集不同,注意这里的边都是无向边。
题解
首先我们发现我们只需要求一个数组f表示有i个点是\(sweet\)的方案数。
然后我们再去搜出所有组合情况来乘一下就好了,这个就是折半搜索+排序+双指针。
然后我们再去设\(g[i]\)表示钦点i个点不能是\(sweet\)的方案数,这个用\(matrix-tree\)高斯消元就可以求出来。
于是:
\]
代码
#include<bits/stdc++.h>
using namespace std;
#define N 43
typedef long long ll;
const int mod=1e9+7;
const int maxn=40;
ll a[N][N],c[N][N],sum[N],f[N],g[N],tong[N],cnt1,cnt2,mxval,x,val[N],num[N];
int n;
inline ll rd(){
    ll x=0;char c=getchar();bool f=0;
    while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
    while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
    return f?-x:x;
}
inline void MOD(ll &x){x=x>=mod?x-mod:x;}
struct node{
    int sum,cnt;
    inline bool operator <(const node &b)const{
        return sum<b.sum;
    }
}a1[1<<20],a2[1<<20];
void dfs1(int now,int sum,int cnt){
    if(now>x){
        a1[++cnt1]=node{sum,cnt};
        return;
    }
    dfs1(now+1,sum,cnt);
    dfs1(now+1,sum+num[now],cnt+1);
}
void dfs2(int now,int sum,int cnt){
    if(now>num[0]){
        a2[++cnt2]=node{sum,cnt};
        return;
    }
    dfs2(now+1,sum,cnt);
    dfs2(now+1,sum+num[now],cnt+1);
}
inline ll power(ll x,ll y){
    ll ans=1;
    while(y){
        if(y&1)ans=ans*x%mod;x=x*x%mod;y>>=1;
    }
    return ans;
}
inline ll ni(ll x){return power(x,mod-2);}
inline ll guass(int n){
   ll ans=1;
   for(int i=1;i<=n;++i)
      for(int j=1;j<=n;++j)MOD(a[i][j]=a[i][j]+mod);
   for(int i=1;i<=n;++i){
       for(int j=i+1;j<=n;++j)if(i!=j){
           ll x=a[j][i]*ni(a[i][i])%mod;
           for(int k=1;k<=n;++k)a[j][k]=(a[j][k]-x*a[i][k]%mod+mod)%mod;
       }
   }
   for(int i=1;i<=n;++i)ans=ans*a[i][i]%mod;
   return ans;
}
inline void solve(){
    num[0]=0;
    memset(tong,0,sizeof(tong));
    memset(f,0,sizeof(f));
    memset(g,0,sizeof(g));
    memset(sum,0,sizeof(sum));
    n=rd();mxval=rd();
    for(int i=1;i<=n;++i)val[i]=rd();
    sort(val+1,val+n+1);
    for(int i=1;i<=n;++i)if(val[i]!=-1){
        num[++num[0]]=val[i];
    }
    for(int i=0;i<=num[0];++i){  //you i ge bu xiang
        memset(a,0,sizeof(a));
        for(int j=1;j<=i;++j)
            for(int k=num[0]+1;k<=n;++k){
                a[j][k]--;a[k][j]--;
                a[j][j]++;a[k][k]++;
            }
        for(int j=i+1;j<=n;++j)
            for(int k=j+1;k<=n;++k){
                a[j][k]--;a[k][j]--;
                a[j][j]++;a[k][k]++;
            }
        g[i]=guass(n-1);
    }
    x=num[0]/2;
    cnt1=cnt2=0;
    dfs1(1,0,0);
    dfs2(x+1,0,0);
    sort(a1+1,a1+cnt1+1);
    sort(a2+1,a2+cnt2+1);
    for(int i=num[0];i>=0;--i){
        f[i]=g[i];
        for(int j=i+1;j<=num[0];++j)MOD(f[i]=f[i]-f[j]*c[num[0]-i][j-i]%mod+mod);
    }
    int p=1;
    for(int i=cnt2;i>=1;--i){
        while(p<=cnt1&&a1[p].sum+a2[i].sum<=mxval){
            tong[a1[p].cnt]++;
            p++;
        }
        for(int j=0;j<=num[0]-a2[i].cnt;++j)MOD(sum[j+a2[i].cnt]+=tong[j]);
    }
    ll ans=0;
  /*  for(int i=0;i<=num[0];++i)cout<<sum[i]<<" ";puts("");
    for(int i=0;i<=num[0];++i)cout<<g[i]<<" ";puts("");
    for(int i=0;i<=num[0];++i)cout<<f[i]<<" ";puts("");*/
    for(int i=0;i<=num[0];++i)MOD(ans+=f[num[0]-i]*sum[i]%mod);
    printf("%lld\n",ans);
}
int main(){
 //   freopen("1.in","r",stdin);
    c[0][0]=1;
    for(int i=1;i<=maxn;++i){
        c[i][0]=1;
        for(int j=1;j<=maxn;++j)MOD(c[i][j]=c[i-1][j]+c[i-1][j-1]);
    }
    int T=rd();
    while(T--)solve();
    return 0;
}
51nod1446 限制价值树的更多相关文章
- [51Nod1446] 限制价值树 (容斥+MT定理+折半搜索)
		传送门 Description 有N个点(N<=40)标记为0,1,2,...N-1,每个点i有个价值val[i],如果val[i]=-1那么这个点被定义为bad,否则如果val[i] > ... 
- 强化学习(六):n-step Bootstrapping
		n-step Bootstrapping n-step 方法将Monte Carlo 与 one-step TD统一起来. n-step 方法作为 eligibility traces 的引入,eli ... 
- [SDOI2008]山贼集团
		题目描述 某山贼集团在绿荫村拥有强大的势力,整个绿荫村由\(N\)个连通的小村落组成,并且保证对于每两个小村落有且仅有一条简单路径相连. 小村落用阿拉伯数字编号为\(1,2,3,4, \dots ,n ... 
- 美团CodeM初赛B轮 合并字符串的价值 (线段树,分类讨论)
		输入两个字符串a和b,合并成一个串c,属于a或b的字符在c中顺序保持不变.如"ACG"和"UT"可以被组合成"AUCTG"或"AC ... 
- HDU 5696 ——区间的价值——————【线段树、快排思想】
		区间的价值 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ... 
- ACM学习历程—HDU5696 区间的价值(分治 && RMQ && 线段树 && 动态规划)
		http://acm.hdu.edu.cn/showproblem.php?pid=5696 这是这次百度之星初赛2B的第一题,但是由于正好打省赛,于是便错过了.加上2A的时候差了一题,当时有思路,但 ... 
- POJ2828 Buy Tickets[树状数组第k小值 倒序]
		Buy Tickets Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 19012 Accepted: 9442 Desc ... 
- D3树状图异步按需加载数据
		D3.js这个绘图工具,功能强大不必多说,完全一个Data Driven Document的绘图工具,用户可以按照自己的数据以及希望实现的图形,随心所欲的绘图. 图形绘制,D3默认采用的是异步加载,但 ... 
- UESTC 764 失落的圣诞节 --RMQ/线段树
		题意:n种物品,每种物品对不同的人都有不同的价值,有三个人选,第一个为普通学生,第二个是集,第三个是祈,集和祈可以选一样的,并且还会获得加分,集和祈选的普通学生都不能选,问三个人怎样选才能使总分最高. ... 
随机推荐
- Java ——日期时间 日期时间相关类 随机数 定义类属性时建议使用引用数据类型
			本节重点思维导图 Date对象创建 两个构造函数: Date() ----使用当前日期和时间来初始化对象 Date(long millisec) -----接收一个参数,该参数是从1970年1月1日起 ... 
- Python解决NameError: name 'reload' is not defined的问题
			遇到这个问题,对于 Python 2.X: import sys reload(sys) sys.setdefaultencoding("utf-8") 对于 Python 3.3 ... 
- vue子组件修改父组件传递过来的值
			这里不再赘述父子组件及子父组件传值,不懂的同学可以翻看我以前写过的关于两者传值的文章 父子组件传值:https://www.cnblogs.com/Sky-Ice/p/9267192.html 子父组 ... 
- 20191105 《Spring5高级编程》笔记-第11章
			第11章 任务调度 任务调度由三部分组成: 任务:需要在特定时间运行或定期运行的业务逻辑块: 触发器:指定任务应该执行的条件: 调度程序:根据来自触发器的信息执行任务: 11.2 Spring中的任务 ... 
- 总结:String类型与Int类型的转换【实现插入操作主键自增】
			1.String类型(此类型是数字格式的字符串类型)转换成Int类型 String str = "10000"; 转换成Int类型: int num = Integer.parse ... 
- hasattr() getattr() setattr() 函数使用详解??
			hasattr(object, name)函数: 判断一个对象里面是否有name属性或者name方法,返回bool值,有name属性(方法)返回True,否则返回False. **注意:name要使用 ... 
- 错误提示控件errorProvider
			http://www.cnblogs.com/suguoqiang/archive/2012/07/17/2596564.html 错误提示控件errorProvider VS显示: 核心代码: th ... 
- Linux基础命令一(补充)
			echo ls ls–l ---- ll cd / 根目录 cd ~ cd - 返回上一个目录 env ip addr 显示物理网络地址,缩写:ip a /etc/init.d/network ... 
- Q开头的类找不到,无法加载插件:com.mysema.maven:apt-maven-plugin
			http://www.jspxcms.com/documentation/297.html 如果出现无法加载com.mysema.maven:apt-maven-plugin插件的情况,通常是由于ma ... 
- 一、Core的布局页、起始页及错误页
			一.布局页面: 使用布局页相当于一个母版页,可以将各个页面公用部分,如上方标题区.左侧导航菜单区.下方版权声明及状态显示区以及通用的js及css引用等,集中放到布局页管理,具体功能页面只需关注自己独有 ... 
