zoukankan      html  css  js  c++  java
  • 洛谷 P5970 [POI2016]Nim z utrudnieniem

    题意

    ( exttt{Nim})游戏,一共(m)颗石子分成了(n)堆,每堆石子数为(a_i),后手可以在游戏开始前扔掉(d)的倍数堆石子,但不能扔掉所有石子,求后手获胜方式有多少种。

    (dleq10,nleq5 imes10^5,a_ileq10^6)(m)不直接给出但保证(mleq10^7)

    思路

    ( exttt{Nim})游戏后手必胜条件:每堆石子的个数异或和为(0)

    (f[i][j][k])表示到第(i)个数,前(i)个数中选出的数的个数( ext{mod} d=j),异或和为(k)的方案数,每次枚举当前堆是否扔掉。

    但是时间复杂度是(O(nmd))的,显然不能过……

    优化需要注意到异或具有的性质:任意个(leq x)的数的异或和(leq2x)。具体来讲就是说任意长度为(k)的数的异或和小于任意长度为(k+1)的数

    因此可以考虑将所有堆的石子数从小到大排序,每次新加入一个数,数的上界一定不会大于(2 imes a_i)

    所以这样时间复杂度就变成了(O(sumlimits_{i=1}^na_id)=O(md))

    但是空间超了,但是只有(kigoplus a_i)(k)之间可以相互转移,所以可以开一个小空间(t),原地完成转移

    还有就是(n)(d)的倍数时会算上全选的情况,此时答案需要减(1)

    常数很大,记得开(O2)

    代码

    /*
    Author:Loceaner
    DP+NIM游戏+状态优化 
    */
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    const int A = 5e5 + 11;
    const int B = (1 << 20) + 11;
    const int mod = 1e9 + 7;
    const int inf = 0x3f3f3f3f;
    
    inline int read() {
      char c = getchar(); int x = 0, f = 1;
      for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
      for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
      return x * f;
    }
    
    int n, d, sum, a[A], t[B], f[10][B], m = 1;
    
    int main() {
      n = read(), d = read();
      for (int i = 1; i <= n; i++) a[i] = read(), sum ^= a[i];
      sort(a + 1, a + 1 + n);
      f[0][0] = 1;
      for (int i = 1; i <= n; i++) {
        while (m <= a[i]) m <<= 1;
        for (int j = 0; j < m; j++) t[j] = f[d - 1][j];
        for (int k = d - 1; k; k--) 
          for (int j = 0; j < m; j++)
            f[k][j] = (f[k][j] + f[k - 1][j ^ a[i]]) % mod;
        for (int j = 0; j < m; j++) f[0][j] = (f[0][j] + t[j ^ a[i]]) % mod;
      }
      cout << (f[0][sum] - (n % d == 0) + mod) % mod << '
    ';
      return 0;
    }
    
  • 相关阅读:
    洛谷 1850 NOIP2016提高组 换教室
    2018牛客多校第三场 C.Shuffle Cards
    2018牛客多校第一场 B.Symmetric Matrix
    2018牛客多校第一场 A.Monotonic Matrix
    2018牛客多校第一场 D.Two Graphs
    2018宁夏邀请赛L Continuous Intervals
    2018宁夏邀请赛K Vertex Covers
    BZOJ
    HDU
    ACM International Collegiate Programming Contest, Egyptian Collegiate Programming Contest (ECPC 2015)
  • 原文地址:https://www.cnblogs.com/loceaner/p/13257899.html
Copyright © 2011-2022 走看看