加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

hdu 6589

发布时间:2020-12-16 09:14:39 所属栏目:百科 来源:网络整理
导读:NTT 首先发现操作的交换不影响答案 然后再打表,发现每项是一个组合数 然后NTT处理就行了 #include bits/stdc++.h using namespace std;typedef long long ll; const int maxn = 2e6 + 5 ,P = 998244353 ; namespace NTT { int power( int x, int t) { int r

NTT

首先发现操作的交换不影响答案

然后再打表,发现每项是一个组合数

然后NTT处理就行了

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e6 + 5,P = 998244353;
namespace NTT {
    int power(int x,int t) {
        int ret = 1;
        for(; t; t >>= 1,x = 1LL * x * x % P) 
            if(t & 1)
                ret = 1LL * ret * x % P;
        return ret;
    }
    void NTT(int *a,int len,int f) {     
        int n = 1 << len;
        for(int i = 0; i < n; ++i) {
            int t = 0;
            for(int j = 0; j < len; ++j) 
                if(i >> j & 1) 
                    t |= 1 << (len - j - 1); 
            if(i < t) swap(a[i],a[t]);
        }
        for(int l = 2; l <= n; l <<= 1) {
            int m = l >> 1;
            int w = power(3,f == 1 ? (P - 1) / l : (P - 1) - (P - 1) / l);
            for(int i = 0; i < n; i += l) {
                int t = 1;
                for(int k = 0; k < m; ++k,t = 1LL * t * w % P) {
                    int x = a[i + k],y = 1LL * t * a[i + m + k] % P;
                    a[i + k] = (x + y) % P;
                    a[i + k + m] = ((x - y) % P + P) % P;
                }
            }       
        }
        if(f == -1) {
            int inv = power(n,P - 2);
            for(int i = 0; i < n; ++i) a[i] = 1LL * a[i] * inv % P;
        }
    }
    void mul(int *a,int *b,int *c,int len) {
        static int tmp[maxn];
        NTT(a,len,1);
        NTT(b,1);
        int n = 1 << len;
        for(int i = 0; i < n; ++i) tmp[i] = 1LL * a[i] * b[i] % P;
        NTT(a,-1);
        NTT(b,-1);
        NTT(tmp,-1);
        for(int i = 0; i < n; ++i) c[i] = tmp[i];
    }
    void mul(int *a,int len) {
        NTT(a,1);
        int n = 1 << len;
        for(int i = 0; i < n; ++i) a[i] = 1LL * a[i] * b[i] % P;
        NTT(a,-1);
    }
} using namespace NTT;
int n,m;
int a[maxn],cnt[5],fac[maxn],facinv[maxn],inv[maxn],b[maxn];
int C(int n,int m) {
    if(n < m) return 0;
    return 1LL * fac[n] * facinv[m] % P * facinv[n - m] % P;
}
int main() {
    fac[0] = 1;
    inv[1] = 1;
    facinv[0] = 1;
    for(int i = 1; i < maxn; ++i) {
        fac[i] = 1LL * fac[i - 1] * i % P;
        if(i != 1) inv[i] = 1LL * (P - P / i) * inv[P % i] % P;
        facinv[i] = 1LL * facinv[i - 1] * inv[i] % P;
    }
    int T; scanf("%d",&T);
    while(T--) {
        memset(cnt,0,sizeof(cnt));
        scanf("%d%d",&n,&m);
        for(int i = 0; i < n; ++i) scanf("%d",&a[i]);
        while(m--) {
            int x; scanf("%d",&x);
            ++cnt[x];
        }
        int t = 0;
        while(1 << t <= 2 * n) ++t;
        int m = 1 << t;
        for(int j = 1; j <= 3; ++j) if(cnt[j]) {
            for(int i = 0; i * j < n; ++i) b[i * j] = C(cnt[j] + i - 1,i);
            mul(a,b,t);
            for(int i = 0; i < m; ++i) b[i] = 0;
            for(int i = n; i < m; ++i) a[i] = 0;
        }
        ll ans = 0;
        for(int i = 0; i < n; ++i) ans ^= 1LL * (i + 1) * a[i];
        printf("%lldn",ans); 
    }
    return 0;
}
View Code

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读