正题
题目链接:https://www.luogu.com.cn/problem/U138404?contestId=36493
题目大意
nnn个数字,每次询问一个区间有多少个三对数或为xxx。
解题思路
首先显然这些数都不能有xxx没有的位数,那么我们选择的数都得是被xxx包含的,这些数的数量很容易求,但是我们还要求每个111位都得有一个数是111。
那么考虑容斥,如果一个xxx的子集yyy的一的个数是比xxx少kkk,那么容斥系数就是(−1)k(-1)^k(−1)k。然后计算即可。
时间复杂度O(28n)O(2^8n)O(28n)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1e5+10;
ll n,Q,a[N],f[N][256],g[256];
ll C3(ll x)
{return x*(x-1)*(x-2)/6;}
int main()
{scanf("%lld%lld",&n,&Q);for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);for(ll j=0;j<256;j++)for(ll i=1;i<=n;i++)f[i][j]=f[i-1][j]+((a[i]|j)==j);g[0]=1;g[1]=-1;for(ll i=2;i<256;i++)g[i]=g[i>>1]*g[i&1];while(Q--){ll l,r,x,ans=0;scanf("%lld%lld%lld",&l,&r,&x);for(ll i=x;i;i=(i-1)&x)ans+=g[x]*g[i]*C3(f[r][i]-f[l-1][i]);printf("%lld\n",ans);}
}