P7386 「EZEC-6」0-1 Trie

P7386 「EZEC-6」0-1 Trie

题目大意

现在 tlx\(n\)\(\mathbf{1}\)\(m\)\(\mathbf{0}\),你需要把它们排列,但要保证任意的 \(\mathbf{1}\) 互不相邻且第一个位置是 \(\mathbf{0}\)、最后一个位置是 \(\mathbf{1}\),现在把所有可以构造出的串放到一棵 0-1 Trie 上,需要多少个节点?

注意:节点计数时,不计算最开始的空节点,只计算代表“ \(\mathbf{0}\) ”、“ \(\mathbf{1}\) ”的节点。

在本题中,我们认为用节点存储字符而非边, Trie 基本原理不变。

因为答案可能很大而且询问较多,所以请在最后输出所有询问的答案对 \(18888913\) (放心,是个质数)取模的结果的异或和(异或和不再进行取模)。

分析

这里不献丑了,直接请参考两位大佬的。

Natsuzora

zmx_wzx_JY

Ac_code

两位推导不太相同但最后公式推导出来后相近。

#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false); cin.tie(0), cout.tie(0)
using namespace std;
typedef long long LL;
const int mod = 18888913;

template<int T>
struct ModInt {
    const static int mod = T;
    int x;
    ModInt(int x = 0) : x(x % mod) {}
    int val() { return x; }
    ModInt operator + (const ModInt &a) const { int x0 = x + a.x; if (x0 >= mod) x0 -= mod; if (x0 < 0) x0 += mod; return ModInt(x0); }
    ModInt operator - (const ModInt &a) const { int x0 = x - a.x; if (x0 >= mod) x0 -= mod; if (x0 < 0) x0 += mod; return ModInt(x0); }
    ModInt operator * (const ModInt &a) const { return ModInt(1LL * x * a.x % mod); }
    ModInt operator / (const ModInt &a) const { return *this * a.inv(); }
    void operator += (const ModInt &a) { x += a.x; if (x >= mod) x -= mod; if (x < 0) x += mod;}
    void operator -= (const ModInt &a) { x -= a.x; if (x < 0) x += mod; if (x >= mod) x -= mod;}
    void operator *= (const ModInt &a) { x = 1LL * x * a.x % mod; }
    void operator /= (const ModInt &a) { *this = *this / a; }
    friend ostream &operator<<(ostream &os, const ModInt &a) { return os << a.x;}
    
    ModInt pow(int n) const {
        ModInt res(1), mul(x);
        while(n){
            if (n & 1) res *= mul;
            mul *= mul;
            n >>= 1;
        }
        return res;
    }
    
    ModInt inv() const {
        int a = x, b = mod, u = 1, v = 0;
        while (b) {
            int t = a / b;
            a -= t * b; swap(a, b);
            u -= t * v; swap(u, v);
        }
        if (u < 0) u += mod;
        return u;
    }
    
};
typedef ModInt<mod> mint;

mint fact[mod],infact[mod];

void init()
{
    fact[0] = infact[0] = 1;
    for(int i=1;i<mod;i++) fact[i] = fact[i-1]*mint(i);
    infact[mod-1] = fact[mod-1].inv();
    for(int i=mod-2;i;i--) infact[i] = infact[i+1]*mint(i+1);
}

mint c(LL a,LL b)
{
    if(a<b) return mint(0);
    return fact[a]*infact[a-b]*infact[b];
}

mint lucas(LL a,LL b)
{
    if(a<mod&&b<mod) return c(a,b);
    return c(a%mod,b%mod)*lucas(a/mod,b/mod);
}

int main()
{
    ios;
    init();
    int T;cin>>T;
    int ans = 0;
    while(T--)
    {
        LL n,m;
        cin>>m>>n;
        if(m>n) continue;
        ans ^= ((mint(2)*lucas(n+1,m) - lucas(n-1,m)) - mint(2)).val();
    }
    cout<<ans<<'\n';
    return 0;
}
posted @ 2022-09-08 20:57  艾特玖  阅读(35)  评论(0)    收藏  举报