zoukankan      html  css  js  c++  java
  • hdu4073 Lights

    题意:找出m个不同的n位2进制数,异或值中前v个为1,其余为0的方案数,答案 % 10567201。。

    思路:比赛时第一感觉是用容斥原理做的,然后推呀推,搞了2个小时还是错了。。赛后才知道递推才是正解(也许容斥是可以的,是我太弱了,推不出吧)

            因为异或的特性,所以这m个数异或为x(前v个为1,其余为0的m位数),相当于这m个数异或x为0,。。

            也就是说如果知道m-1个数,第m个数也唯一被确定了。。

            假设f[m]为m个数的方案数,那么不考虑重复的情况下,f[m] = C(2^n, m-1)

            那么如何去除重复了,如果出现重复(一定最多只有两个数重复),那么这两个书异或值为0,发现什么了没有。。

            也就是去掉这两个数,就是f[m-2]了吧。。

            除此之外,对于合法的每一组方案,会算m次吧

           so,f[m] = (C(2^n, m-1) - f[m-2] * (2^n - (m-2))) / m;

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <string>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <cstdlib>
     9 #include <sstream>
    10 #include <fstream>
    11 #include <list>
    12 #include <deque>
    13 #include <queue>
    14 #include <stack>
    15 #include <map>
    16 #include <set>
    17 #include <bitset>
    18 #include <cctype>
    19 #include <ctime>
    20 #include <utility>
    21 #define M0(x) memset(x, 0, sizeof(x))
    22 #define clr(x,y) memset(x, y, sizeof(x))
    23 #define P 10567201
    24 #define N 1010
    25 using namespace std;
    26 long long c[1010][1010], two[1010];
    27 int n, m, v;
    28 long long f[N+5], inv[N+5];  
    29 using namespace std;
    30 
    31 void get_inv(){
    32     inv[1] = 1;
    33     for (int i = 2; i < N; ++i)
    34         inv[i] = (P - P / i) * inv[P % i] % P;
    35 }
    36 
    37 void pre_do(){
    38      get_inv();
    39      two[0] = 1;
    40      for (int i = 1; i < N; ++i){
    41          two[i] = (two[i-1] << 1);
    42          if (two[i] >= P) two[i] -= P;
    43     }
    44     for (int i = 1; i < N; ++i){
    45          c[i][0] = 1;
    46          for (int j = 1; j < N; ++j)
    47              c[i][j] = c[i][j-1] * (two[i]-j+1) % P * inv[j] % P;    
    48     }
    49 }
    50 
    51 void solve(){
    52      if (v == 0) f[0] = 1;
    53      else f[0] = 0;
    54      f[1] = 1;
    55      for (int i = 2; i <= m; ++i){
    56         long long same = f[i-2] * (two[n]-i+2) % P;
    57         f[i] = (c[n][i-1] - same) * inv[i] % P;
    58      }
    59      f[m] += (f[m] < 0 ? P : 0); 
    60      printf("%I64d
    ", f[m]);
    61 }
    62 
    63 int main(){
    64 //    freopen("a.in","r",stdin);
    65 //    freopen("a.out","w",stdout);
    66     pre_do();
    67     while (scanf("%d%d%d", &n, &m, &v) != EOF){
    68          if (!(n+m+v)) break;
    69          solve();
    70     }
    71     return 0;
    72 }

       

  • 相关阅读:
    STL set
    STL pair
    STL简介
    最长公共子序列lcs
    MySQL常用内置函数整理
    MySQL注入点写webshell的五种方式
    phpAdmin写webshell的方法
    mysql之突破secure_file_priv写webshell
    MySQL提权之启动项提权
    MySQL提权之mof提权
  • 原文地址:https://www.cnblogs.com/yzcstc/p/3932677.html
Copyright © 2011-2022 走看看