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\) (放心,是个质数)取模的结果的异或和(异或和不再进行取模)。
分析
这里不献丑了,直接请参考两位大佬的。
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;
}

浙公网安备 33010602011771号