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; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步