異或之Kth[1] (可持久化二進位制trie樹)
【問題描述】
給出n個非負整數A[1]..A[n],程式設計回答詢問:
1 k x:詢問 x xor A[i] (1<=i<=n) 中第k小的值。
2 k l r x:詢問 x xor A[i] (l<=i<=r) 中第k小的值。
【輸入格式】
第一行為整數n。
第二行為n個非負整數,表示A[1],A[2],…,A[n]。
第三行為整數m。
之後的m行,每行表示一種詢問。
【輸出格式】
對於每個詢問,給出你的回答。
【輸入樣例】
5
1 2 3 4 5
2
1 4 3
2 2 3 5 2
【輸出樣例】
6
6
【資料範圍】
n,m<=500000
A[i],x均在unsigned long long 範圍,所有詢問均合法
【來源】
Mr_he原創
一道可持久化的二進位制trie樹,寫法類似權值線段樹的Kth,只需要記錄每個點的下面包含多少個數就可以了。
詳細程式碼如下:
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
using namespace std;
typedef unsigned long long ull;
const int maxn=500005;
int root[maxn],s[maxn*32]={0},ch[maxn*32][2]={0},cnt=0,n;
void up(int x)
{
s[x]=s[ch[x][0]]+s[ch[x][1]];
}
void in(int pre,int &now,int i,ull x)
{
now=++cnt;
ch[now][0]=ch[pre][0];
ch[now][1]=ch[pre][1];
s[now]=s[pre];
if(i<0) {s[now]++;return;}
int d=(x>>i)&1;
in(ch[pre][d],ch[now][d],i-1,x);
up(now);
}
ull read()
{
ull x=0;
char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
ull find(int pre,int now,int i,int k,ull &x)
{
if(i<0) return 0;
int d=(x>>i)&1;
int t=s[ch[now][d]]-s[ch[pre][d]];
if(t<k)
{
return find(ch[pre][d^1],ch[now][d^1],i-1,k-t,x)+((ull)1<<i);
}
else return find(ch[pre][d],ch[now][d],i-1,k,x);
}
char q[50];
void out(ull x)
{
if(!x)
putchar('0');
int tot=0;
while(x)
{
q[++tot]=x%10;
x/=10;
}
for(int i=tot;i>=1;i--) putchar(q[i]+'0');
putchar('\n');
return;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
n=read();
ull x,ans;
for(int i=1;i<=n;i++)
{
x=read();
in(root[i-1],root[i],63,x);
}
int l,r,k,id;
int m=read();
while(m--)
{
id=read();
if(id==1)
{
k=read();x=read();
ans=find(root[0],root[n],63,k,x);
}
if(id==2)
{
k=read();l=read();r=read();x=read();
ans=find(root[l-1],root[r],63,k,x);
}
out(ans);
}
return 0;
}
相關文章
- poj 3764 最長異或路徑(二進位制trie樹)
- 可持久化trie持久化
- 可持久化 01 trie持久化
- 二進位制或序列
- bzoj 4546: codechef XRQRS [可持久化Trie]持久化
- 複習(二):KMP、Trie、最大異或對、KMP
- 二進位制、十進位制與十六進位制相互轉化
- 進位制之間的轉換之“十六進位制 轉 十進位制 轉 二進位制 方案”
- 二進位制,八進位制,十進位制,十六進位制之間的轉換
- P4551 最長異或路徑(樹上字首異或01-trie)
- js 許可權二進位制JS
- 大話二進位制,八進位制,十進位制,十六進位制之間的轉換
- 【主席樹】P3919 【模板】可持久化線段樹 1持久化
- 二進位制與二進位制運算
- 實現整數二進位制指定位置為0或1
- 對2個hex(16進位制)字串進行異或操作字串
- 進位制詳解:二進位制、八進位制和十六進位制
- JavaScript 二進位制、八進位制與十六進位制JavaScript
- 3416:【例72.1】 二進位制轉化為十進位制
- 【JVM】或許,這就是二進位制Class吧JVM
- 二進位制檔案視覺化(二)視覺化
- (二進位制)
- 二進位制
- 二進位制中1的個數
- 十進位制——二 (八、十六 )進位制
- 二進位制,八進位制,十進位制,十六進位制的相互轉換
- 【進位制轉換】二進位制、十六進位制、十進位制、八進位制對應關係
- 二進位制漏洞挖掘之整數溢位
- java中二進位制、八進位制、十進位制、十六進位制的轉換Java
- Python 進位制互相轉換(二進位制、十進位制和十六進位制)Python
- Carthage和iOS元件二進位制化iOS元件
- 計算機基礎進位制轉換(二進位制、八進位制、十進位制、十六進位制)計算機
- Swift之struct二進位制大小分析SwiftStruct
- 二進位制轉十進位制快速方法
- JAVA 二進位制,八進位制,十六進位制,十進位制間進行相互轉換Java
- 一段對16進位制字串進行異或的程式碼字串
- 什麼是二進位制?二進位制如何轉換?
- 二進位制求5個1的格式。。。。