zoukankan      html  css  js  c++  java
  • 【SRM】518 Nim

    题意

    (K(1 le K le 10^9))堆石子,每堆石子个数不超过(L(2 le 50000)),问Nim游戏中先手必败局面的数量,答案对(10^9+7)取模。

    分析

    容易得到(f(i, k) = sum_{j=0}^{n-1} f(i-1, j) f(i-1, k^j), f(1, i(2 le i le L))=1),其中(n=min(2^i, 2^i > L))。发现其实这就是操作为(xor)的卷积。于是用鬼畜的fwt做就行了。

    题解

    然后fwt+快速幂即可。

    // BEGIN CUT HERE
    
    // END CUT HERE
    #line 5 "Nim.cpp"
    #include <bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int mo=1e9+7, N=100005, two=(1e9+8)/2;
    void fwt(int *a, int l, int r, int f) {
    	if(r-l==1) {
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(!f) {
    		fwt(a, l, mid, f);
    		fwt(a, mid, r, f);
    	}
    	int g=f?two:1;
    	for(int i=l, m=(r-l)>>1; i<mid; ++i) {
    		int x=a[i], y=a[i+m];
    		a[i]=(ll)(x+y)%mo*g%mo;
    		a[i+m]=(ll)(x-y+mo)%mo*g%mo;
    	}
    	if(f) {
    		fwt(a, l, mid, f);
    		fwt(a, mid, r, f);
    	}
    }
    int ipow(int a, int b) {
    	int x=1;
    	for(; b; b>>=1, a=(ll)a*a%mo) {
    		if(b&1) {
    			x=(ll)x*a%mo;
    		}
    	}
    	return x;
    }
    int a[N];
    class Nim {
    public:
    	int count(int K, int L) {
    		int len=1;
    		for(; len<=L; len<<=1);
    		memset(a, 0, sizeof(int)*len);
    		for(int i=2; i<=L; ++i) {
    			a[i]=1;
    		}
    		for(int i=2; i<=L; ++i) {
    			if(a[i]) {
    				for(int j=i+i; j<=L; j+=i) {
    					a[j]=0;
    				}
    			}
    		}
    		fwt(a, 0, len, 0);
    		for(int i=0; i<len; ++i) {
    			a[i]=ipow(a[i], K);
    		}
    		fwt(a, 0, len, 1);
    		return a[0];
    	}
    
    // BEGIN CUT HERE
    	public:
    	void run_test(int Case) { if ((Case == -1) || (Case == 0)) test_case_0(); if ((Case == -1) || (Case == 1)) test_case_1(); if ((Case == -1) || (Case == 2)) test_case_2(); if ((Case == -1) || (Case == 3)) test_case_3(); }
    	private:
    	template <typename T> string print_array(const vector<T> &V) { ostringstream os; os << "{ "; for (typename vector<T>::const_iterator iter = V.begin(); iter != V.end(); ++iter) os << '"' << *iter << "","; os << " }"; return os.str(); }
    	void verify_case(int Case, const int &Expected, const int &Received) { cerr << "Test Case #" << Case << "..."; if (Expected == Received) cerr << "PASSED" << endl; else { cerr << "FAILED" << endl; cerr << "	Expected: "" << Expected << '"' << endl; cerr << "	Received: "" << Received << '"' << endl; } }
    	void test_case_0() { int Arg0 = 3; int Arg1 = 7; int Arg2 = 6; verify_case(0, Arg2, count(Arg0, Arg1)); }
    	void test_case_1() { int Arg0 = 4; int Arg1 = 13; int Arg2 = 120; verify_case(1, Arg2, count(Arg0, Arg1)); }
    	void test_case_2() { int Arg0 = 10; int Arg1 = 100; int Arg2 = 294844622; verify_case(2, Arg2, count(Arg0, Arg1)); }
    	void test_case_3() { int Arg0 = 123456789; int Arg1 = 12345; int Arg2 = 235511047; verify_case(3, Arg2, count(Arg0, Arg1)); }
    
    // END CUT HERE
    
    };
    
    // BEGIN CUT HERE
    int main() {
    	Nim ___test;
    	___test.run_test(-1);
    	return 0;
    }
    // END CUT HERE
  • 相关阅读:
    java异常处理 it
    java文件操作 it
    ArrayLike it
    javaProreties it
    javaset,Collections,map it
    003 Longest Substring Without Repeating Characters it
    react Video event it
    查看git地址
    Itext 生成PDF
    jar包配置文件到单独文件夹
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4986434.html
Copyright © 2011-2022 走看看