C0392 B 【1109 B组】预处理器 题解
题意:求有多少个长度为
-
条件一:
l_{i} \le a_{i} \le r_{i} 。 -
条件二:
a_{i} 模2 等于p_{i} 。 -
条件三:
s \le \sum a_{i} \le t 。
求答案模
数据范围:
又积累到一个新的 Trick:看到这种
显然,
发现可以把条件三转化为
那对于每一个
注意:
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 15;
int n,s,t,mod,a[MAXN][2],p[MAXN];
inline int solve(int x)
{
int ans = 0;
for(int i = 0;i < (1 << n);i++)
{
int tot = x,op = __builtin_popcount(i) & 1;
for(int j = 1;j <= n;j++)
{
if((i >> j - 1) & 1) tot -= a[j][1] + 1,tot -= (p[j] ^ (a[j][1] + 1)) & 1;
else tot -= a[j][0],tot -= (p[j] ^ a[j][0]) & 1;;
}
if(tot < 0) continue;
tot = tot / 2,tot += n;
int res = 1,vis[MAXN] = {},a[MAXN],p = 1;
for(int j = 1;j <= n;j++) p = p * j;
for(int j = 1;j <= n;j++)
{
int val = tot - j + 1;
int g = __gcd(val,p);
val /= g,p /= g;
a[j] = val;
}
for(int j = 1;j <= n;j++) res = (res * a[j]) % mod;
ans = (ans + res * (1 - 2 * op) + mod) % mod;
}
return ans;
}
signed main()
{
cin >> n >> s >> t >> mod;
for(int i = 1;i <= n;i++) cin >> a[i][0] >> a[i][1] >> p[i];
cout << (solve(t) - solve(s - 1) + mod) % mod;
return 0;
}