版权声明:本文为博主原创文章,转载时请标明出处。 https://blog.csdn.net/FarmerJohnOfZS/article/details/78796753
Description
“~妖梦,我又饿了!”
魂魄妖梦身为西行寺家的专属庭师第二代兼大小姐的西行寺幽幽子的护卫,却承担了为幽幽子准备食物的任务。幽幽子是个非常贪吃的亡灵,所以妖梦经常为食物的问题所困。
现在,妖梦有n盘食物排成一排,第i盘食物有一个属性a[i]。亡灵的体质比较特殊,所以妖梦认为食物的属性很重要。妖梦会进行q次询问,每次给出两个整数r,k,她想知道有多少个区间[i,r](1≤i≤r),区间内所有食物属性值的异或大于等于k。
100%:1≤n,q≤100000 r≤n 0≤k,a[i]≤1,000,000,000
Solution
离线处理问题
在 Trie 上处理
注意到
在 Trie 上存属性的异或值的前缀和
根据异或的性质去做即可
Code
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define fo(i,x,y) for (int pq = (y),i = (x);i <= pq;++ i)
#define fd(i,x,y) for (int pq = (y),i = (x);i >= pq;-- i)
#define oo 2139062143
using namespace std;
typedef double db;
typedef long long ll;
int lowbit(int x) {return((x)&(-x));}
int min(int x,int y){return (x>y)?(y):(x);}
int max(int x,int y){return (x>y)?(x):(y);}
const int N=100100;
struct qy{
int r,k,pos;
}p[N];
int n,q;
int a[N],ans[N];
bool gt(int x,int y)//x binary NO.y
{
return(x&(1<<(y-1)));
}
bool cmpr(qy x,qy y)
{
return(x.r<y.r);
}
int sz[N*30],chd[N*30][2],col[N*30];
int tot=1;
void insert(int now,int v,int p)
{
++sz[now];
if(!p) return;
int tmp=gt(v,p);
if(!chd[now][tmp]) chd[now][tmp]=++tot,col[tot]=tmp;
insert(chd[now][tmp],v,p-1);
}
int query(int now,int v,int p,int xr)
{
if(!sz[now])
return 0;
if(p==1)
return ((col[now]^gt(xr,p))>=gt(v,p))?sz[now]:0;
if((col[now]^gt(xr,p))>gt(v,p))
return(sz[now]);
if((col[now]^gt(xr,p))==gt(v,p))
return(query(chd[now][0],v,p-1,xr)+query(chd[now][1],v,p-1,xr));
if((col[now]^gt(xr,p))<gt(v,p))
return 0;
}
int main()
{
freopen("food.in","r",stdin);
freopen("food.out","w",stdout);
scanf("%d",&n);
fo(i,1,n) scanf("%d", &a[i]),a[i]^=a[i-1];
scanf("%d",&q);
fo(i,1,q)
{
scanf("%d%d",&p[i].r,&p[i].k);
p[i].pos=i;
}
sort(p+1,p+1+q,cmpr);
p[0].r=1;
insert(1,0,30);
fo(i,1,q)
{
fo(j,p[i-1].r,p[i].r-1)
insert(1,a[j],30);
ans[p[i].pos]=query(chd[1][0],p[i].k,30,a[p[i].r])+query(chd[1][1],p[i].k,30,a[p[i].r]);
}
fo(i,1,q) printf("%d\n",ans[i]);
return 0;
}