Bzoj4568: [Scoi2016]幸运数字

线性基+倍增+LCA

原来线性基还能这么考……一开始看到这个题以为是树上差分线性基,然而线性基不支持删除,所以就挂了。

后来想到倍增线性基,其实到这里思路就很清晰了。

倍增线性基,A[i][j]表示从i开始向上2j步的线性基,询问时暴力合并即可。

 1 xxj hb(xxj a,xxj b)
 2 {
 3     xxj ans;ans.qk();
 4     for(int i=0;i<=60;i++)
 5     {
 6         if(a.b[i])ans.ins(a.b[i]);//不加if会T
 7         if(b.b[i])ans.ins(b.b[i]);
 8     }
 9     return ans;
10 }

  1 //幸运数字
  2 #include<iostream>
  3 #include<cstdio>
  4 #define MAXN 20010
  5 #define LL long long
  6 const int L=1<<20|1;
  7 char buffer[L],*S,*T;
  8 #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
  9 using namespace std;
 10 struct xxj
 11 {
 12     LL b[65];
 13     void qk()
 14     {
 15         for(int i=0;i<=64;i++)b[i]=0;
 16     }
 17     bool ins(LL x)
 18     {
 19         for(int i=60;i>=0;i--)
 20         if(x&(1ll<<i))
 21         {
 22             if(!b[i]){b[i]=x;break;}
 23             else x=x^b[i];
 24         }
 25         if(x)return 1;
 26         else return 0;
 27     }
 28     LL findmax()
 29     {
 30         LL ans=0;
 31         for(int i=60;i>=0;i--)
 32             ans=max(ans,ans^b[i]);
 33         return ans;
 34     }
 35 }A[MAXN][16],ta;
 36 xxj hb(xxj a,xxj b)
 37 {
 38     xxj ans;ans.qk();
 39     for(int i=0;i<=60;i++)
 40     {
 41         if(a.b[i])ans.ins(a.b[i]);
 42         if(b.b[i])ans.ins(b.b[i]);
 43     }
 44     return ans;
 45 }
 46 struct edge
 47 {
 48     int u,v,nxt;
 49     #define u(x) ed[x].u
 50     #define v(x) ed[x].v
 51     #define n(x) ed[x].nxt
 52 }ed[MAXN*2];
 53 int first[MAXN],num_e;
 54 #define f(x) first[x]
 55 LL n,q,g[MAXN];
 56 int fa[MAXN][16],dep[MAXN];
 57 void dfs(int x,int ff,int de)
 58 {
 59     fa[x][0]=ff;dep[x]=de;A[x][0].ins(g[x]);//A[x][0].ins(g[ff]);
 60     for(int i=f(x);i;i=n(i))
 61     if(v(i)!=ff)dfs(v(i),x,de+1);
 62 }
 63 int LCA(int x,int y)
 64 {
 65     if(dep[x]>dep[y])swap(x,y);
 66     for(int i=15;i>=0;i--)
 67         if(dep[fa[y][i]]>=dep[x])
 68             y=fa[y][i];
 69     if(x==y)return x;
 70     for(int i=15;i>=0;i--)
 71         if(fa[x][i]!=fa[y][i])
 72             x=fa[x][i],y=fa[y][i];
 73     return fa[x][0];
 74 }
 75 inline LL read()
 76 {
 77     LL s=0;char a=getchar();
 78     while(a<'0'||a>'9')a=getchar();
 79     while(a>='0'&&a<='9'){s=s*10+a-'0';a=getchar();}
 80     return s;
 81 }
 82 inline void adde(int u,int v);
 83 signed main()
 84 {
 85 //    freopen("10.in","r",stdin);
 86
 87     n=read(),q=read();
 88     for(int i=1;i<=n;i++)g[i]=read();
 89     int a,b;
 90     for(int i=1;i<n;i++)
 91     {
 92         a=read(),b=read();
 93         adde(a,b);adde(b,a);
 94     }
 95     dfs(1,0,1);
 96     for(int i=1;i<=15;i++)
 97         for(int j=1;j<=n;j++)
 98         {
 99             fa[j][i]=fa[fa[j][i-1]][i-1];
100             A[j][i]=hb(A[j][i-1],A[fa[j][i-1]][i-1]);
101         }
102     for(int i=1;i<=q;i++)
103     {
104         int xi=read(),yi=read();
105         int lca=LCA(xi,yi);
106         ta.qk();
107         for(int j=15;j>=0;j--)
108         if(dep[fa[xi][j]]>=dep[lca])
109             ta=hb(ta,A[xi][j]),xi=fa[xi][j];
110         for(int j=15;j>=0;j--)
111         if(dep[fa[yi][j]]>=dep[lca])
112             ta=hb(ta,A[yi][j]),yi=fa[yi][j];
113         ta.ins(g[lca]);
114         printf("%lld\n",ta.findmax());
115     }
116 }
117 inline void adde(int u,int v)
118 {
119     ++num_e;
120     u(num_e)=u;
121     v(num_e)=v;
122     n(num_e)=f(u);
123     f(u)=num_e;
124 }

完整代码

转载于:https://www.cnblogs.com/Al-Ca/p/11240190.html

Bzoj4568: [Scoi2016]幸运数字相关推荐

  1. BZOJ4568 [Scoi2016]幸运数字

    BZOJ4568 [Scoi2016]幸运数字 题目描述 传送门 题目分析 这个题,求树上链的\(XOR\)最大值,可以不选某些点. 考虑到线性基可以用很快的速度求出\(XOR\)的最大值,我们首先可 ...

  2. [BZOJ4568][SCOI2016]幸运数字(倍增LCA,点分治+线性基)

    4568: [Scoi2016]幸运数字 Time Limit: 60 Sec  Memory Limit: 256 MB Submit: 2131  Solved: 865 [Submit][Sta ...

  3. [bzoj4568][Scoi2016]幸运数字

    来自FallDream的博客,未经允许,请勿转载,谢谢. A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这 ...

  4. BZOJ4568: [Scoi2016]幸运数字(线性基 倍增)

    题意 题目链接 Sol 线性基是可以合并的 倍增维护一下 然后就做完了?? 喵喵喵? // luogu-judger-enable-o2 #include<bits/stdc++.h> # ...

  5. BZOJ4568 : [Scoi2016]幸运数字

    树的点分治,每次求出重心后,求出重心到每个点路径上的数的线性基. 对于每个询问,只需要暴力合并两个线性基即可. 时间复杂度$O(60n\log n+60^2q)$. #include<cstdi ...

  6. P3292 [SCOI2016]幸运数字(树剖 + 线段树维护线性基)

    P3292 [SCOI2016]幸运数字 思路 如果这题是求x,yx, yx,y之间的距离显然我们可以通过树剖加线段树来写, 但是这里变成了求任意个数的异或最大值.如果给定区间我们显然可以通过线性基来 ...

  7. [洛谷P3292] [SCOI2016]幸运数字

    洛谷题目链接:[SCOI2016]幸运数字 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城 ...

  8. bzoj 4568: [Scoi2016]幸运数字(树上倍增+线性基)

    4568: [Scoi2016]幸运数字 Time Limit: 60 Sec  Memory Limit: 256 MB Submit: 1692  Solved: 643 [Submit][Sta ...

  9. BZOJ4568:[SCOI2016]幸运数字——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4568 https://www.luogu.org/problemnew/show/P3292 A ...

最新文章

  1. QT中关于ipv6和getaddressinfo的开关
  2. 微信小程序获取用户手机号--官方示例
  3. 单元测试之DBUnit的使用以及原理剖析
  4. [leetcode]83.删除排序链表中的重复元素
  5. windows 改变文件大小 函数_手写 bind call apply 方法 与 实现节流防抖函数
  6. 资源集 - 收藏集 - 掘金
  7. 斑马无线打印服务器,如何设置斑马打印机无线WiFi
  8. 02 - 替换SetInput方法 VTK 6.0 迁移 (2013-06-30 16:22)
  9. 教你使用Vue.js的DevTools来调试你的vue项目
  10. 马云:首批助力欧洲防疫的物资今天到达比利时
  11. C++安全方向opensssl(三)3.1 什么是单项散列函数
  12. java 枚举_深入理解Java枚举
  13. 【.Net MF网络开发板研究-06】以太网转串口
  14. 《国际学术论文写作与发表》课后题
  15. c语言 饱和加法,[转载]优化饱和加法运算
  16. 用户特殊权限SUID,SGID, SBIT理解学习
  17. Idea scalac: Scala compiler JARs not found (module ‘XXXX‘): C:\Users\nanhu\.cache\co......
  18. 开源项目推荐:Bezier曲线、B-Spline和NURBS的区别与《THE NURBS BOOK 2nd》简介,曲线拟合可视化工具
  19. php中{ifp}{ife}{ifpp}是什么意思、作用
  20. 下载USGS的地物光谱数据库的网址

热门文章

  1. getDeclaredField和getField的区别
  2. zookeeper(一):功能和原理
  3. C# 退出提示 事件提示两次问题
  4. PaaS case study
  5. report things that go wrong
  6. 在这个领域发一篇最有影响力的期刊,这是一个well qualified的phd学生应该做的
  7. sun building in shanghai
  8. gmail怎么延时发送邮件呢?
  9. ifm virtual check in part 2
  10. 不再有神的概念,将所有存在称之为文明,这很有意思