BZOJ 4103: [Thu Summer Camp 2015]异或运算 可持久化trie

开始想了一个二分+可持久化trie验证,比正解多一个 log  

仔细思考,你发现你可以直接按位枚举,然后在可持久化 trie 上二分就好了. 

code: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <bits/stdc++.h> 
#define N 700005  
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;     
int n,m,tot,tl,tr;     
int ch[N*30][2],cnt[N*30],xx[N],yy[N],rt[N],t1[N],t2[N];        
void insert(int pre,int &x,int v)
{
    int now=x=++tot;       
    for(int i=30;i>=0;--i)
    {
        int o=((v>>i)&1);   
        ch[now][o^1]=ch[pre][o^1];  
        ch[now][o]=++tot;   
        pre=ch[pre][o];
        now=ch[now][o]; 
        cnt[now]=cnt[pre]+1;  
    }
}         
int query(int L,int R,int kth,int len)
{
    if(len<0)     return 0;  
    int re=0,cur=1,i;
    for(cur=1,i=L;i<=R;++i,++cur)
    {
        int o=((xx[i]>>len)&1);  
        re+=cnt[ch[t2[cur]][o^1]]-cnt[ch[t1[cur]][o^1]];   
    }   
    if(kth<=re)
    {  
        for(cur=1,i=L;i<=R;++i,++cur)  
        {
            int o=((xx[i]>>len)&1);  
            t1[cur]=ch[t1[cur]][o^1];  
            t2[cur]=ch[t2[cur]][o^1];   
        }  
        return (1<<len)+query(L,R,kth,len-1);
    }
    else
    {
        for(cur=1,i=L;i<=R;++i,++cur)
        {
            int o=((xx[i]>>len)&1);  
            t1[cur]=ch[t1[cur]][o]; 
            t2[cur]=ch[t2[cur]][o];  
        
        return query(L,R,kth-re,len-1);  
    }
}
int main()
{  
    // setIO("input");  
    int i,j; 
    scanf("%d%d",&n,&m);  
    for(i=1;i<=n;++i)    scanf("%d",&xx[i]);  
    for(i=1;i<=m;++i)   
    {
        scanf("%d",&yy[i]);
        insert(rt[i-1],rt[i],yy[i]);  
    }       
    int q;
    scanf("%d",&q);
    while(q--)
    {
        int a,b,c,d,k;
        scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);             
        tl=tr=0; 
        for(i=a;i<=b;++i)       t1[++tl]=rt[c-1],t2[tl]=rt[d];      
        printf("%d\n",query(a,b,k,30));              
    }
    return 0;
}

  

 

posted @   EM-LGH  阅读(120)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示