zoukankan      html  css  js  c++  java
  • 牛客挑战赛36 G Nim游戏(分治FWT)

    https://ac.nowcoder.com/acm/contest/3782/G

    题解:

    分治FWT裸题。

    每个都相当于((1+b[i]x^{a[i]})),求这玩意的异或卷积。

    先把a[i]相同的并在一起。

    考虑分治,一个区间内的数的二进制的前若干位是相同的,所以只需要记录这个区间的数选了奇数还是偶数个以及后面的二进制位每一个异或结果的系数。

    考虑合并,两个子区间二进制位上只有一个不同,那么右区间用了奇数个的话,这一位+1就好了。

    写递归似乎常数比较大。

    Code:

    #include<bits/stdc++.h>
    #define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
    #define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
    #define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
    #define ll long long
    #define pp printf
    #define hh pp("
    ")
    using namespace std;
    
    #define gc getchar
    template<class T> void read(T &x) {
    	char c = ' '; x = 0;
    	while(c < '0' || c > '9') c = gc();
    	for(; c >= '0' && c <= '9'; c = gc()) x = x * 10 + c - '0';
    }
    
    const int mo = 998244353;
    
    ll ksm(ll x, ll y) {
    	ll s = 1;
    	for(; y; y /= 2, x = x * x % mo)
    		if(y & 1) s = s * x % mo;
    	return s;
    }
    
    const int N = 131072;
    
    
    int n, x, y;
    ll f[N][2], a[N], b[N];
    
    void fwt(ll *a, int n, int f) {
    	ll b;
    	for(int i = 1; i < n; i *= 2) for(int j = 0; j < n; j += 2 * i) ff(k, 0, i)
    		b = a[i + j + k], a[i + j + k] = a[j + k] - b, a[j + k] += b;
    	ff(i, 0, n) a[i] %= mo;
    	if(f == -1) {
    		b = ksm(n, mo - 2);
    		ff(i, 0, n) a[i] = a[i] * b % mo;
    	}
    }
    
    ll g[N][2];
    
    void dg(int x, int y) {
    	if(x == y) return;
    	int m = x + y >> 1;
    	dg(x, m); dg(m + 1, y);
    	int n = y - m;
    	fo(k, x, y) g[k][0] = g[k][1] = 0;
    	fo(i, 0, 1) fo(j, 0, 1) {
    		fo(k, x, m) a[k - x] = f[k][i];
    		fo(k, m + 1, y) b[k - (m + 1)] = f[k][j];
    		fwt(a, n, 1); fwt(b, n, 1);
    		ff(k, 0, n) a[k] = a[k] * b[k] % mo;
    		fwt(a, n, -1);
    		ff(k, 0, n) g[x + k + j * (x ^ (m + 1))][i ^ j] += a[k];
    	}
    	fo(k, x, y) f[k][0] = g[k][0] % mo, f[k][1] = g[k][1] % mo;
    }
    
    int main() {
    	scanf("%d", &n);
    	ff(i, 0, N) f[i][0] = 1;
    	fo(i, 1, n) {
    		read(x); read(y);
    		ll f0 = f[x][0];
    		f[x][0] = (f[x][0] + f[x][1] * y) % mo;
    		f[x][1] = (f[x][1] + f0 * y) % mo;
    	}
    	dg(0, N - 1);
    	ll ans = (f[0][0] + f[0][1] - 1 + mo + mo) % mo;
    	pp("%lld
    ", ans);
    }
    
  • 相关阅读:
    Appium+python自动化13-native和webview切换【转载】
    Appium+python自动化12-appium元素定位【转载】
    Appium+python自动化11-adb必知必会的几个指令【转载】
    Appium+python自动化10-AVD 模拟器【转载】
    Appium+python自动化9-SDK Manager【转载】
    Appium+python自动化8-Appium Python API【转载】
    Appium+python自动化7-输入中文【转载】
    Appium+python自动化6-Remote远程控制【转载】
    Appium+python自动化5-Appium Inspector【转载】
    Centos-内核核心组成
  • 原文地址:https://www.cnblogs.com/coldchair/p/12374521.html
Copyright © 2011-2022 走看看