1. 程式人生 > >Educational Codeforces Round 23 E. Choosing The Commander (trie)

Educational Codeforces Round 23 E. Choosing The Commander (trie)

ati -- main 刪除 span std ble targe pla

題目鏈接: Educational Codeforces Round 23 E. Choosing The Commander

題意:

一共有n個操作。

1. 插入一個數p

2. 刪除一個數p

3. 詢問有多少個數 使得 x^p<l

題解:

對於前兩種操作用01trie就能解決。

對於對三個操作,我們考慮在trie上搜索。

1. 當l的bit位是1時,那邊bit位是p的字數全部的數都會小於l,(因為p^p=0)

2. 當l的bit為是0時,那邊只能向bit位是p的子樹中搜。

這樣算下來 三種操作的時間復雜度都為log(1e8)。總復雜度為nlog(1e8)

技術分享
 1 #include<bits/stdc++.h>
 2
#define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5 const int N=2e6+7; 6 int n,tr[N][2],cnt[N],ed=1,type,p,l; 7 8 void add(int x,int v) 9 { 10 int now=1; 11 for(int i=30;i>=0;i--) 12 { 13 int tp=bool(x&(1<<i)); 14 if(!tr[now][tp])tr[now][tp]=++ed;
15 cnt[now]+=v,now=tr[now][tp]; 16 } 17 cnt[now]+=v; 18 } 19 20 int ask(int p,int l,int now=1,int bit=30) 21 { 22 if(!now||bit<0)return 0; 23 int pp=bool(p&(1<<bit)); 24 if(l&(1<<bit))return cnt[tr[now][pp]]+ask(p,l,tr[now][pp^1],bit-1); 25 else return
ask(p,l,tr[now][pp],bit-1); 26 } 27 28 int main(){ 29 scanf("%d",&n); 30 while(n--) 31 { 32 scanf("%d%d",&type,&p); 33 if(type==1)add(p,1); 34 else if(type==2)add(p,-1); 35 else scanf("%d",&l),printf("%d\n",ask(p,l)); 36 } 37 return 0; 38 }
View Code

Educational Codeforces Round 23 E. Choosing The Commander (trie)