考虑异或最短路应该怎么求。那么这是个WC原题,dfs一遍找到所有有用的环丢进线性基即可,因为每一个环的权值都是可以取到且不对其他部分产生影响的。

  现在给了一棵树,不妨就把他看做原图的dfs树。每增加一条边就是增加了一个环。算出权值后,现在问题变为求一个数和任选一段区间里的数的最大异或值。

  比较暴力的做法是直接建线段树,每次logn*log2v取出区间线性基。这样可以拿50分。

  线性基的合并实在太慢了。考虑能不能离线搞。每次取出跨过区间中点的询问,处理中点左右的后缀前缀线性基,询问时将两边线性基合并。于是就变成logv(logn+logv)了。

  调了半天发现m和n搞反了。

  果然是NOIp模拟。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cassert>
using namespace std;
int read()
{int x=0,f=1;char c=getchar();while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();return x*f;
}
#define N 300010
int n,m,q,p[N],deep[N],value[N],ans[N],t=0;
struct base
{int size,a[31];void ins(int x){for (register int i=30;~i;i--){if (!x) break;if (x&(1<<i))if (!a[i]) {a[i]=x;size++;break;}else x^=a[i];}}base operator +(const base&b) const{base c;if (size>b.size){c.size=size;for (int i=0;i<31;i++) c.a[i]=a[i];if (size==31) return c;for (register int i=30;~i;i--)c.ins(b.a[i]);}else{c.size=b.size;for (int i=0;i<31;i++) c.a[i]=b.a[i];if (b.size==31) return c;for (register int i=30;~i;i--)c.ins(a[i]);}return c;}
}pre[N],suf[N];
struct data{int to,nxt,len;
}edge[N<<1];
struct data2{int i,l,r,x;
}Q[N],u[N];
void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
void dfs(int k,int from)
{for (int i=p[k];i;i=edge[i].nxt)if (edge[i].to!=from){deep[edge[i].to]=deep[k]^edge[i].len;dfs(edge[i].to,k);}
}
int work(int x,base p)
{for (int i=30;~i;i--)x=min(x,x^p.a[i]);return x;
}
void solve(int l,int r,int low,int high)
{if (l>r||low>high) return;if (low==high){for (int i=l;i<=r;i++) ans[Q[i].i]=min(Q[i].x,Q[i].x^value[low]);return;}int mid=low+high>>1;for (int i=mid;i>=low;i--){if (i==mid) pre[i]=(base){0,{0}};else pre[i]=pre[i+1];pre[i].ins(value[i]);}for (int i=mid+1;i<=high;i++){if (i==mid+1) suf[i]=(base){0,{0}};else suf[i]=suf[i-1];suf[i].ins(value[i]);}int head=l-1,tail=r+1;for (int i=l;i<=r;i++)if (Q[i].l<=mid&&Q[i].r>mid) ans[Q[i].i]=work(Q[i].x,pre[Q[i].l]+suf[Q[i].r]);else if (Q[i].r<=mid) u[++head]=Q[i];else u[--tail]=Q[i];for (int i=l;i<=r;i++) Q[i]=u[i];solve(l,head,low,mid);solve(tail,r,mid+1,high);
}
int main()
{
#ifndef ONLINE_JUDGEfreopen("c.in","r",stdin);freopen("c.out","w",stdout);const char LL[]="%I64d\n";
#elseconst char LL[]="%lld\n";
#endifn=read(),m=read(),q=read();for (int i=1;i<n;i++){int x=read(),y=read(),z=read();addedge(x,y,z),addedge(y,x,z);}dfs(1,1);for (int i=1;i<=m;i++){int x=read(),y=read(),z=read();value[i]=deep[x]^deep[y]^z;}for (int i=1;i<=q;i++){int s=read(),t=read(),l=read(),r=read();Q[i].i=i,Q[i].x=deep[s]^deep[t],Q[i].l=l,Q[i].r=r;}solve(1,q,1,m);for (int i=1;i<=q;i++) printf("%d\n",ans[i]);return 0;
}

转载于:https://www.cnblogs.com/Gloid/p/9658421.html

#41 最短路(分治+线性基)相关推荐

  1. BZOJ.4184.shallot(线段树分治 线性基)

    BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...

  2. 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横

    不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...

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

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

  4. 【CF1100F】 Ivan and Burgers (分治+线性基)

    description 戳我看题目(づ ̄3 ̄)づ╭❤- solution 异或和最大 --关联线性基 线性基: 原序列的每一个数都能由线性基里若干个数异或得到 线性基里若干个数的异或结果不可能为0 如 ...

  5. LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset

    题目:https://loj.ac/problem/2312 https://www.luogu.org/problemnew/show/P3733 原本以为要线段树分治+LCT,查了查发现环上的值直 ...

  6. CF938G Shortest Path Queries(线性基/线段树分治/异或)

    CF938G Shortest Path Queries 支持加边删边和查询两点之间的异或最短路,我们可以使用线段树分治,然后利用线性基求解. 但是这里图可能不是联通的,所以查询两点之间的异或和需要边 ...

  7. BZOJ 4184 shallot 线性基+分治

    Description 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且让小葱从 ...

  8. P3733 [HAOI2017]八纵八横(线性基/线段树分治)

    P3733 [HAOI2017]八纵八横 这是那道线性基的加强版,现在要求从1节点出发的一条路径异或和最大,并且还要支持修改权值和加边删边. 我们可以直接线段树分治然后将所有修改用vector存下来, ...

  9. CF938G Shortest Path Queries(线性基,线段树分治,并查集)

    CF938G Shortest Path Queries Solution 套路题. xorxorxor最短路可以用线性基维护(把每个环的边权异或和放进线性基,询问时把树边路径边权异或和放在线性基里跑 ...

最新文章

  1. 引入外部css_css
  2. 线程同步——内核对象实现线程同步——等待函数
  3. System.Insert - 插入字符串
  4. JS导出 excel
  5. 《时间管理:如何充分利用你的24小时》—让你时间发挥最大效用
  6. BackTrack5 安装中文输入法
  7. Linux系统中硬盘的管理
  8. php get header url,php函数get_headers是HEAD请求还是GET请求
  9. 兄弟9055cdn硒鼓清零_兄弟打印机清零设置
  10. 计算机概论读后感,电子商务概论读后感.doc
  11. 动词ing形式做定语的用法总结
  12. 面试了一个 37 岁程序员,让我有所触动,35岁以上的程序员该何去何从?
  13. Excel函数sumproduct应用案例-多条件求和
  14. Python+Selenium+unittest demo
  15. python数据分析——pandas
  16. standard、singleTop、singleTask和singleInstance原理分析
  17. “疯狂”抗癌史:从以毒攻毒,再到用犯人进行试验,成就一个诺奖
  18. STM32F103CBT6和STM32F103ZET6单片机进行程序移植
  19. DVWA靶场-sql盲注
  20. ASP.NET 使用日期控件

热门文章

  1. 澎湖县地产泡沫的破灭
  2. Fedora 30系统下,用g++编译opencv项目
  3. FPGA实验——译码器原理及实现
  4. ipc620中文版最新版本_(一)Windows10 家庭中文版Docker安装 搭建docker开发环境
  5. pytorch用win还是Linux,如何在Windows系统安装使用机器学习库PyTorch
  6. python序列类型举例说明_Python基础__Python序列基本类型及其操作(1)
  7. 5u fb库 三菱plc_三菱FX5U PLC入门必备基础知识特点
  8. python为什么从0开始_为什么大多数编程语言中,索引都是从0开始
  9. SQL语言包含4个部分
  10. / /* /**的区别