• HNOI2011 卡农


    讲个笑话:我的做法是 (O(nlog n))

    Description

    link

    有对于一个给定的集合 (S=1...n) ,选取其中 (m) 个子集要求子集非空,不能相同,并且每个出现过的元素出现次数是偶数

    (n,m le 10^6)

    Solution

    这个题要求组合的方案,先转化一步:求排列的方案然后除以阶乘

    状态:(f_i) 为取 (i) 个集合的方案

    之后发现一个性质:我们确定前 (i-1) 个集合,最后一个就被自然确定了

    (补全原来没有拿成偶数的元素即可)

    这样我们发现取 (m) 个集合的方案是:(A_{2^{n-1}}^{i-1})

    这样我们发现可能不太对

    (1.) 最后一个集合是空集,即原来取的方案已经满足所有的元素出现的个数为偶数

    解决方案:直接(f[i]-=f[i-1];)

    (2.) 最后一个集合和原来的集合是重复的

    最后一个集合可能和原来的 (i-1) 个的重复,此时我们拿出那两个重复的集合,还剩余 (i-2)

    (i-2) 的方案是有 (f_{i-2})

    重复的集合的可能有(sum(2^n-1)-exist(i-2)) 括号里的是真值

    理解就是总的个数和最后剩下没有重复的个数

    重复集合的位置有 (i-1) 种(有序计数)

    预处理阶乘逆元和排列数即可

    讲述前面的那个笑话:考虑到我闲的就把 (2^n) 求了 (n)

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=1e6+10,mod=1e8+7;
    	int inv,p,f[N],n,m,a[N];
    	inline int ksm(int x,int y)
    	{
    		int res=1; for(;y;y>>=1,(x*=x)%=mod) if(y&1) (res*=x)%=mod;
    		return res;
    	}
    	int num;
    	signed main()
    	{
    		n=read(); m=read(); inv=1;
    		for(int i=1;i<=m;++i) inv*=i,inv%=mod; inv=ksm(inv,mod-2);
    		a[0]=1; for(int i=1;i<=m;++i) a[i]=a[i-1]*((ksm(2,n)-i+mod)%mod)%mod;
    		f[0]=1;
    		for(int i=2;i<=m;++i)
    		{
    			f[i]=(a[i-1]-f[i-1]+mod)%mod; 
    			f[i]-=f[i-2]*(i-1)%mod*((ksm(2,n)-1-(i-2)+mod)%mod)%mod;
    			(f[i]+=mod)%=mod;
    		}
    		cout<<f[m]*inv%mod<<endl;
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    

    Review

    组合计数不好求的时候可以考虑转排列求阶乘

    再一个就是数学的分类讨论一定要细致求好

  • 相关阅读:
    数据持久化
    在职场久了,才知道这样安排工作日程,方能实现真正的高效
    HIS系统-如何设置单病种结算方式
    HIS系统-你给我制作一个二级库吧!
    开机的一篇英文是怎么回事呢?
    系统故障之-冲动360
    每天看一遍你潦倒至今的原因
    如何配置给自己配置一台适合自己的台式机
    如何配置给自己配置一台电脑
    单网卡、双网卡如何实现同时上内网和外网
  • 原文地址:https://www.cnblogs.com/yspm/p/12790172.html
Copyright © 2020-2023  润新知