light oj-1269
来源:互联网 发布:米思米选型软件2017 编辑:程序博客网 时间:2024/05/21 17:37
1269 - Consecutive Sum
自己犯了一个shab错误结果debug半小时。。
题意:n个数,要你从这n个数中分别找两个区间,使得区间内的数异或值最大和最小。
思路:字典树异或裸题,以前没做过这种同时求最大最小值的,于是板子来了一发。
把每个数的前缀异或和扔进字典树,然后查找只需扫一遍过去,先把当前值的前缀异或和从字典树中删去,然后查找最小值只需将当前位置的前缀异或和的二进制直接查找下去,而查询最大值则需要把二进制翻转,然后沿着字典树走下去,如果为1,说明有贡献,加上即可。
注意返回的都只是这n个前缀异或除去当前位的某一个。在开始插入之间先将0插入字典树中。
动态字典树:
const int N=50000+10;int cnt,n,a[35];ll sum[N];struct tree{ int f; tree *next[2]; tree() { next[0]=next[1]=NULL; f=0; }};//tree mem[N*40];void ch(ll x){ memset(a,0,sizeof(a)); int len=0; while(x) a[len++]=(x&1),x/=2;}void insert(tree *root,ll x){ ch(x); int len=32; tree *p=root; while(len>=0) { int id=a[len]; if(p->next[id]==NULL) p->next[id]=new tree(); p=p->next[id]; p->f++; len--; }}ll find(tree *root){ tree *p=root; int len=32; ll ans=0; while(len>=0) { int id=a[len]; if(p->next[id]==NULL||p->next[id]->f==0) id^=1; p=p->next[id]; if(id) ans+=ll(1)<<len; len--; } return ans;}void del(tree *root){ tree *p=root; int len=32; while(len>=0) { int id=a[len]; p=p->next[id]; p->f--; len--; }}void dele(tree *root){ for(int i=0; i<2; i++) if(root->next[i]) dele(root->next[i]); delete(root);}int main(){ int t,x; scanf("%d",&t); int t1=t; while(t--) { scanf("%d",&n);// memset(mem,0,sizeof(mem)); cnt=sum[0]=0; tree *root=new tree(); insert(root,sum[0]); for(int i=1; i<=n; i++) { scanf("%d",&x); sum[i]=sum[i-1]^x; insert(root,sum[i]); } ll ma=0,mi=INF; for(int i=1; i<=n; i++) { ch(sum[i]); del(root); mi=min(mi,sum[i]^find(root)); for(int j=0; j<33; j++) a[j]^=1; ma=max(ma,sum[i]^find(root)); insert(root,sum[i]); } printf("Case %d: %lld %lld\n",t1-t,ma,mi); dele(root); } return 0;}
静态字典树:
const int N=50000+10;int cnt,n,a[35];ll sum[N];struct tree{ int f; tree *next[2];};tree mem[N*40];void ch(ll x){ memset(a,0,sizeof(a)); int len=0; while(x) a[len++]=(x&1),x/=2;}void insert(tree *root,ll x){ ch(x); int len=32; tree *p=root; while(len>=0) { int id=a[len]; if(p->next[id]==NULL) p->next[id]=&mem[cnt++]; p=p->next[id]; p->f++; len--; }}ll find(tree *root){ tree *p=root; int len=32; ll ans=0; while(len>=0) { int id=a[len]; if(p->next[id]==NULL||p->next[id]->f==0) id^=1; p=p->next[id]; if(id) ans+=ll(1)<<len; len--; } return ans;}void del(tree *root){ tree *p=root; int len=32; while(len>=0) { int id=a[len]; p=p->next[id]; p->f--; len--; }}int main(){ int t,x; scanf("%d",&t); int t1=t; while(t--) { scanf("%d",&n); cnt=sum[0]=0; memset(mem,0,sizeof(mem)); tree *root=&mem[cnt++]; insert(root,sum[0]); for(int i=1; i<=n; i++) { scanf("%d",&x); sum[i]=sum[i-1]^x; insert(root,sum[i]); } ll ma=0,mi=INF; for(int i=1; i<=n; i++) { ch(sum[i]); del(root); mi=min(mi,sum[i]^find(root)); for(int j=0; j<33; j++) a[j]^=1; ma=max(ma,sum[i]^find(root)); insert(root,sum[i]); } printf("Case %d: %lld %lld\n",t1-t,ma,mi); } return 0;}
阅读全文
0 0
- light oj-1269
- light oj
- light oj
- Light OJ
- Light OJ
- Light OJ 1000
- Light OJ 1001
- Light OJ 1008
- Light OJ 1022
- Light OJ 1015
- Light OJ 1042
- light oj 1128
- Light OJ 1055 BFS
- Light OJ Beginners Problems
- Light OJ Basic Geometry
- Light OJ Basic Math
- light oj 1124
- Light OJ 1012
- 下载或移除 Chrome 主题背景
- Web Service (001---schema)
- 使用Hadoop和Spark实现TopN算法(1)——唯一键
- <c语言经典100例>c29:判断回文数
- java版云笔记(六)之AOP
- light oj-1269
- java中局部变量和成员变量的区别
- Java环境变量的配置与检验
- 【洛谷】P3195【HNOI2008】玩具装箱TOY
- hdu4587TWO NODES【割点】
- ARC 083E
- Web Service (002---HTTP)
- 机器学习总结 第一课
- HTML 标题 段落 图像 链接