• [题解] [Codechef] CNTDSETS


    题面

    题解

    由于会出现重复的情况, 我们考虑如何去掉这种情况

    我们可以这样考虑, 若每一维的最小值都为 (0) , 那么我们将这一种情况算作合法情况

    同理, 若某几维的最小值不为 (0) , 我们必定可以经过平移将它的这一维移至 (0) , 所以这一种情况我们不算进去

    这样就可以不重不漏的算出有多少个集合了, 并且该点集中每个点每一维都 (in [0, d])

    考虑容斥计算总方案数, 设 (f(d)) 代表直径 (leq d) 的点集有多少个

    [displaystyle f(d) = sum_{i = 0}^{n}(-1)^iinom{n}{i}2^{d^i(d+1)^{n-i}} ]

    我们考虑枚举有至少 (i) 维差的最大值 (< d) , 从 (n) 各种选出 (i) 个, 有 (inom{n}{i}) 种可能

    又因为至少有 (i) 维最大值 (< d) , 故这一维一共有 ([1, d])(d) 种选法

    其他的维每一维都有 ([0, d])(d + 1) 中选法

    拼起来就有 (d^i(d + 1)^{n - i}) 种可以选的点, 每个点可选可不选, 所以有 (2 ^ {d^i(d + 1)^{n - i}}) 种选法

    注意 (2) 的幂次要用欧拉定理取模

    再乘上容斥系数 ((-1)^i) 即可

    Code

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    const int mod = 1000000007;
    const int N = 1005; 
    using namespace std;
    
    int T, n, d, c[N][N]; 
    
    template < typename T >
    inline T read()
    {
    	T x = 0, w = 1; char c = getchar();
    	while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
    	while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    	return x * w; 
    }
    
    int fpow(int x, int y, int p)
    {
    	int res = 1;
    	for( ; y; y >>= 1, x = 1ll * x * x % p)
    		if(y & 1) res = 1ll * res * x % p; 
    	return res; 
    }
    
    int f(int n, int d)
    {
    	int res = 0; 
    	for(int i = 0; i <= n; i++)
    		res = (1ll * res + (1ll * (i & 1 ? -1 : 1) * c[n][i] * fpow(2, 1ll * fpow(d, i, mod - 1) * fpow(d + 1, n - i, mod - 1) % (mod - 1), mod) % mod + mod) % mod) % mod; 
    	return res; 
    }
    
    int main()
    {
    	T = read <int> ();
    	for(int i = 0; i <= 1000; i++)
    		for(int j = 0; j <= i; j++)
    			c[i][j] = (!j ? 1 : (c[i - 1][j - 1] + c[i - 1][j]) % mod);
    	while(T--)
    	{
    		n = read <int> (), d = read <int> ();
    		printf("%d
    ", (f(n, d) - f(n, d - 1) + mod) % mod); 
    	}
    	return 0; 
    }
    
  • 相关阅读:
    学习进度第三周
    四则运算3
    学习进度第二周
    单元测试
    四则运算2
    学习进度第一周
    四则运算1
    构建之法阅读笔记01
    linux: 讨论一下网络字节序--------大端与小端的差别
    linux编程:线程条件同步
  • 原文地址:https://www.cnblogs.com/ztlztl/p/12204215.html
Copyright © 2020-2023  润新知