题意:
给你一个整数数组 nums (下标 从 0 开始 计数)以及两个整数:low 和 high ,请返回 漂亮数对 的数目。
漂亮数对 是一个形如 (i, j) 的数对,
其中 0 <= i < j < nums.length 且 low <= (nums[i] XOR nums[j]) <= high 。
数据范围:
1 <= nums.length <= 2 * 1e4
1 <= nums[i] <= 2 * 1e4
1 <= low <= high <= 2 * 1e4
解法:
题目是对于每个j,查询有多少个i,满足lc<=(a[i]^a[j])<=rc.
设f(x)为与a[j]异或<=x的i的数量,那么可以将问题变为:
对于每个j,查询f(rc)-f(lc-1),
f(rc)可以通过在字典树上dfs实现.
code:
const int maxm=1e5+5;
struct TT{
int a[maxm][32],tot;
int cnt[maxm];
void init(){
for(int i=0;i<=tot;i++){
memset(a[i],0,sizeof a[i]);
cnt[i]=0;
}
tot=0;
}
void add(int x){
int node=0;
for(int i=30;i>=0;i--){
int v=(x>>i&1);
if(!a[node][v])a[node][v]=++tot;
node=a[node][v];
cnt[node]++;
}
}
int ask(int x,int ma){
if(ma<0)return 0;
int node=0;
int ans=0;
for(int i=30;i>=0;i--){
int v=(x>>i&1);
int vv=(ma>>i&1);
if(v&&vv){
ans+=cnt[a[node][1]];
node=a[node][0];
}else if(v&&!vv){
node=a[node][1];
}else if(!v&&vv){
ans+=cnt[a[node][0]];
node=a[node][1];
}else if(!v&&!vv){
node=a[node][0];
}
if(!node)return ans;
}
ans+=cnt[node];
return ans;
}
}T;
class Solution {
public:
int countPairs(vector<int>& a, int lc, int rc) {
T.init();
int n=a.size();
int ans=0;
T.add(a[0]);
for(int i=1;i<n;i++){
int t=T.ask(a[i],rc)-T.ask(a[i],lc-1);
cout<<i<<' '<<t<<endl;
ans+=t;
T.add(a[i]);
}
return ans;
}
};