zoukankan      html  css  js  c++  java
  • hdu4073 Lights

    Description

    John has (n) light bulbs and a switchboard with (n) switches; each bulb can be either on or off, and pressing the (i)-th switch changes the state of bulb (i) from on to off, and viceversa. He is using them to play a game he has made up. In each move, John selects a (possibly empty) set of switches and presses them, thus inverting the states of the corresponding bulbs. After exactly (m) moves, John would like to have the first (v) bulbs on and the rest off; otherwise he loses the game. There is only one restriction: he is not allowed to press the same set of switches in two different moves.
    This is quite an easy game, as there are lots of ways of winning. This has encouraged him to keep playing different winning games, and now he is intent on trying them all. Help him count how many ways of winning there are. Two games are considered the same if, after a reordering of the moves in one of them, at every step the same set of switches is pressed in both of them.
    For example, if (n = 4, m = 3), and (v = 2), one possible winning game is obtained by pressing switches (1), (2) and (4) in the first move, (1) and (3) in the second one, and (1), (3) and (4) in the last one. This is considered equivalent to, say, first pressing (1) and (3); then (1,2, 4); and then (1, 3, 4).

    Input

    The input has at most (500) lines, one for each test case. Each line contains three integers (n (1 le n le 1 000), m (1 le m le 1 000)), and (v (0 le v le n)). The last line of input will hold the values (0; 0;0) and must not be processed.

    Output

    Print one line for each test case containing the number of ways John can play the game, modulo the prime (10 567 201).

    Sample Input

    3 3 1
    6 4 0
    6 4 3
    0 0 0

    Sample Output

    7
    10416
    9920

    (f_i)表示(i)次操作使得前(v)盏灯亮着的合法方案数。利用容斥原理转移

    [f_i = left( inom{2^n}{i-1} - left( 2^n - left( i - 2 ight) ight) imes f_{i-2} ight)/i ]

    注意细节:(f_0)的初值与(v)有关。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    
    typedef long long ll;
    const int rhl = 10567201,maxn = 1010;
    int N,M,V,f[maxn],mi[maxn],inv[maxn],C[maxn];
    
    inline int qsm(ll a,int b)
    {
    	ll ret = 1;
    	for (;b;b >>= 1,(a *= a) %= rhl) if (b&1) (ret *= a) %= rhl;
    	return (int)ret;
    }
    
    inline int gi()
    {
    	char ch; int ret = 0,f = 1;
    	do ch = getchar(); while (!(ch >= '0'&&ch <= '9')&&ch != '-');
    	if (ch == '-') f = -1,ch = getchar();
    	do ret = ret*10+ch-'0',ch = getchar(); while (ch >= '0'&&ch <= '9');
    	return ret*f;
    }
    
    int main()
    {
    	freopen("4073.in","r",stdin);
    	freopen("4073.out","w",stdout);
    	mi[0] = 1;
    	for (int i = 1;i <= 1000;++i)
    	{
    		mi[i] = mi[i-1]<<1;
    		if (mi[i] >= rhl) mi[i] -= rhl;
    	}
    	for (int i = 1;i <= 1000;++i) inv[i] = qsm(i,rhl-2);
    	while (true)
    	{
    		N = gi(); M = gi(); V = gi();
    		if (!N && !M && !V) break;
    		f[0] = (V == 0); C[0] = 1;
    		for (int i = 1;i <= M;++i)
    		{
    			C[i] = (ll)C[i-1]*(ll)(mi[N]-i+1)%rhl*(ll)inv[i]%rhl;
    			if (C[i] < 0) C[i] += rhl;
    		}
    		for (int i = 1;i <= M;++i)
    		{
    			f[i] = C[i-1];
    			if (i >= 2) f[i] -= (ll)(mi[N]-(i-2))*(ll)f[i-2]%rhl;
    			if (f[i] < 0) f[i] += rhl;
    			f[i] = (ll)f[i]*(ll)inv[i]%rhl;
    		}
    		cout << f[M] << endl;
    	}
    	fclose(stdin); fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    HDU 2767 Proving Equivalences(强连通缩点)
    HDU 3836 Equivalent Sets(强连通缩点)
    POJ 2762 Going from u to v or from v to u?(强连通+缩点+拓扑排序)
    织梦dedecms中自定义表单必填项的设置方法
    dedecms中调用隐藏栏目的方法
    去掉dedecms友情链接中的LI标签的方法
    Mysql修改端口号 织梦DedeCMS设置教程
    织梦DedeCMS文章标题自动增加长尾关键词的方法
    DEDECMS短标题标签调用与字数修改的方法
    dedecms批量替换文章中超链接的方法
  • 原文地址:https://www.cnblogs.com/mmlz/p/6403828.html
Copyright © 2011-2022 走看看