[THUSC2015] 异或运算

P5795 [THUSC2015] 异或运算

题目描述

给定长度为 n 的数列 X=x1,x2,...,xn 和长度为 m 的数列 Y=y1,y2,...,ym,令矩阵 A 中第 i 行第 j 列的值 Ai,j=xi xor yj,每次询问给定矩形区域 i[u,d],j[l,r],找出第 k 大的 Ai,j

对于 100% 的数据

  • 0Xi,Yj<231,
  • 1udn1000,
  • 1lrm300000,
  • 1k(du+1)×(rl+1), 1p500

Solution:

我们发现数据范围十分的有意思,n,m及其的不对称,并且我们唯一能接受的多项式复杂度是 O(nqlogm)

我们维护一个可持久化 0/1 Trie,用来存每个b的值。然后对于每个查询,从31位开始往0位扫,在这个矩形中统计一下当前位 ig 为1的有多少,而统计的方式自然就是遍历 i[u,d] 查询对于每个 xi ,假设它的第 ig 位是 now。我们需要统计在 t[l1]+t[r] 这颗树上,第 ig 位是 !now 的节点数

如果cntk,说明这位必须取1,且将所有的主席树节点访问到 !now 如果不取的话那么排名至少为 cnt+1

如果 cnt<k,说明这位不能取1,但是在当前位 igcnt 个比 ans 大的数,所以在我们的主席树进入 now 统计答案之前要先将 k=cnt

然后这题就做完了

Code:

#include<bits/stdc++.h>
const int N=3e5+5;
using namespace std;
int a[N],b[N];
struct Trie{
int cnt;
int rt[N],L[N],R[N];
struct Tree{
int ch[2],cnt;
}t[N*50];
inline void insert(int &x,int y,int val,int len)
{
t[x=++cnt]=t[y];
t[x].cnt++;
if(len<0)return ;
int now=(val>>len)&1;
insert(t[x].ch[now],t[y].ch[now],val,len-1);
}
int query(int x,int y,int l,int r,int k)
{
int res=0;
for(int i=x;i<=y;i++)
{
L[i]=rt[l-1];
R[i]=rt[r];
}
for(int ig=31;ig>=0;ig--)
{
int cnt=0;
for(int i=x;i<=y;i++)
{
int now=(a[i]>>ig)&1;
cnt+= -t[t[L[i]].ch[!now]].cnt+t[t[R[i]].ch[!now]].cnt;
}
if(cnt>=k)//这一位取1至少有 k 个 (这一位如果不取1,排名至少是cnt+1)
{
res|=(1<<ig);//这位要取1
for(int i=x;i<=y;i++)
{
int now=(a[i]>>ig)&1;
L[i]=t[L[i]].ch[!now];
R[i]=t[R[i]].ch[!now];
}
}
else //这位不取1
{
k-=cnt;
for(int i=x;i<=y;i++)
{
int now=(a[i]>>ig)&1;
L[i]=t[L[i]].ch[now];
R[i]=t[R[i]].ch[now];
}
}
}
return res;
}
}T;
int n,m,q;
void work()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=m;i++)
{
scanf("%d",&b[i]);
T.insert(T.rt[i],T.rt[i-1],b[i],31);
}
cin>>q;
for(int i=1,x,y,l,r,k;i<=q;i++)
{
scanf("%d%d%d%d%d",&x,&y,&l,&r,&k);
int ans=T.query(x,y,l,r,k);
printf("%d\n",ans);
}
}
int main()
{
//freopen("P5795_1.in","r",stdin);freopen("P5795.out","w",stdout);
work();
return 0;
}
posted @   liuboom  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示