题意

给一棵 n n n个节点的树,边有边权。定义一条路径的权值为边权的异或和。找两条节点不相交的路径,使得这两条路径的权值和最大。
n ≤ 30000 n\le 30000 n≤30000

分析

问题可以转化成对于每个点,求在该点的子树内和子树外分别找两个数,使得它们的异或的和尽可能大。
求出dfs序并倍增,就可以转化成在区间中选两个数,使得这两个数的异或和尽可能大。
用回滚莫队+Trie就好了。
回滚莫队具体来讲,就是左右端点都在同一个块内的询问直接暴力搞。把其他询问以左端点所在的块为第一关键字,右端点为第二关键字排序。在处理某个块内的询问的时候,记录 a n s ans ans表示该块的右端点到右指针的答案。每次把右指针推到询问的右端点,再把左指针从块的右端点推到询问的左端点,之后把左指针恢复就好了。
时间复杂度 O ( n n log ⁡ V ) O(n\sqrt n\log V) O(nn ​logV).

代码

#include<bits/stdc++.h>
#define pb push_backconst int N=30005;int n,cnt,last[N],bel[N],tim,dfn[N],val[N],w[N*2],mx[N],sz,tot,B,bin[35],ans[N],rt;
struct edge{int to,next,w;}e[N*2];
struct data{int l,r,id;}q[N*2];
struct tree{int l,r,s;}t[N*30];
std::vector<int> vec[N];void addedge(int u,int v,int w)
{e[++cnt].to=v;e[cnt].w=w;e[cnt].next=last[u];last[u]=cnt;e[++cnt].to=u;e[cnt].w=w;e[cnt].next=last[v];last[v]=cnt;
}void dfs(int x,int fa)
{dfn[x]=++tim;bel[tim]=x;for (int i=last[x];i;i=e[i].next)if (e[i].to!=fa) val[e[i].to]=val[x]^e[i].w,dfs(e[i].to,x);mx[x]=tim;
}int cmp(int x,int y)
{return q[x].r<q[y].r;
}int get(int x)
{return (x+B-1)/B;
}void ins(int &x,int d,int w,int c)
{if (!x) x=++sz;t[x].s+=c;if (d<0) return;if (w&bin[d]) ins(t[x].r,d-1,w,c);else ins(t[x].l,d-1,w,c);
}int query(int x,int d,int w)
{if (d<0) return 0;if (w&bin[d])if (t[t[x].l].s) return query(t[x].l,d-1,w)+bin[d];else return query(t[x].r,d-1,w);elseif (t[t[x].r].s) return query(t[x].r,d-1,w)+bin[d];else return query(t[x].l,d-1,w);
}int calc(int l,int r)
{int mx=0;for (int i=l;i<=r;i++) mx=std::max(mx,query(rt,30,w[i])),ins(rt,30,w[i],1);for (int i=l;i<=r;i++) ins(rt,30,w[i],-1);return mx;
}void pre()
{B=sqrt(n*2);for (int i=1;i<=n;i++) w[i]=w[i+n]=val[bel[i]];for (int i=2;i<=n;i++){int l=dfn[i],r=mx[i],pos=get(l);if (get(l)==get(r)) ans[i]+=calc(l,r);else q[++tot].l=l,q[tot].r=r,q[tot].id=i,vec[pos].pb(tot);l=mx[i]+1;r=dfn[i]+n-1;pos=get(l);if (get(l)==get(r)) ans[i]+=calc(l,r);else q[++tot].l=l,q[tot].r=r,q[tot].id=i,vec[pos].pb(tot);}for (int i=1;i<=get(n*2);i++) std::sort(vec[i].begin(),vec[i].end(),cmp);
}void solve()
{for (int i=1;i<=get(n*2);i++){int r=B*i-1,mx=0;for (int j=0;j<vec[i].size();j++){int now=vec[i][j],tmp=0;while (r<q[now].r) mx=std::max(mx,query(rt,30,w[++r])),ins(rt,30,w[r],1);int l=B*i;while (l>q[now].l) tmp=std::max(tmp,query(rt,30,w[--l])),ins(rt,30,w[l],1);while (l<B*i) ins(rt,30,w[l++],-1);ans[q[now].id]+=std::max(mx,tmp);}while (r>B*i-1) ins(rt,30,w[r--],-1);}
}int main()
{bin[0]=1;for (int i=1;i<=30;i++) bin[i]=bin[i-1]*2;scanf("%d",&n);for (int i=1;i<n;i++){int x,y,z;scanf("%d%d%d",&x,&y,&z);addedge(x,y,z);}dfs(1,0);pre();solve();int mx=0;for (int i=2;i<=n;i++) mx=std::max(mx,ans[i]);printf("%d\n",mx);return 0;
}

【洛谷P6072 [MdOI2020] Path】【回滚莫队+Trie】相关推荐

  1. 【周末狂欢赛6】[AT1219]历史研究(回滚莫队),大魔法师(矩阵+线段树),单峰排列

    文章目录 T1:单峰排列 题目 题解 code T2:历史研究 题目 题解 code T3:大魔法师 题目 题解 code 我可能这辈子都更不出来狂欢赛5了,先咕咕 T1:单峰排列 题目 一个n的全排 ...

  2. 【莫队/树上莫队/回滚莫队】原理详解及例题:小B的询问(普通莫队),Count on a tree II(树上莫队),kangaroos(回滚莫队)

    文章目录 问题引入 介绍莫队算法及其实现过程 时间复杂度 莫队算法适用范围 莫队奇偶优化 普通莫队:小B的询问 树上莫队:SP10707 COT2 - Count on a tree II 回滚莫队: ...

  3. AT1219-歴史の研究(历史研究)【回滚莫队】

    正题 题目链接:https://www.luogu.com.cn/problem/AT1219 题目大意 nnn个数字,mmm次询问一个区间内ti∗it_i*iti​∗i的最大值,tit_iti​即区 ...

  4. BZOJ4241历史研究题解--回滚莫队

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=4241 分析 这题就是求区间权值乘以权值出现次数的最大值,一看莫队法块可搞,但仔细想想,莫 ...

  5. 历史研究(回滚莫队)

    问题 C: 历史研究 时间限制: 1 Sec  内存限制: 128 MB 提交: 61  解决: 2 [提交] [状态] [命题人:admin] 题目描述 IOI 国历史研究的大牛--JOI 教授,最 ...

  6. 【练习】BZOJ4241: 历史研究(回滚莫队)

    题意 给定一个长度为 n n n的序列,并提出q" role="presentation">qqq个询问,每次询问要求回答区间 [l,r] [ l , r ] [l ...

  7. 洛谷-小清新人渣的本愿-(莫队+bitset)

    小清新人渣的本愿 题意: 就是给你一个数组,然后有3种查询,分别是问你l到r区间内,是否有两个数的差等于x,只和等于x,乘积为x. 思考: 其实看到,感觉就挺复杂的,没办法去找这种关系对,除了乘积为x ...

  8. 2021牛客第五场 I.Interval Queries-回滚莫队

    如图:一道很裸的回滚莫队,注意加入的操作和回滚的操作就好了. #include <cstdio> #include <cstring> #include <string& ...

  9. 洛谷P4287 [SHOI2011]双倍回文 题解

    洛谷P4287 [SHOI2011]双倍回文 题解 题目链接:P4287 [SHOI2011]双倍回文 题意: 记字符串 www 的倒置为 wRw^RwR .例如 (abcd)R=dcba(\tt{a ...

最新文章

  1. SpringCloud中Feign的适配器的实现方案
  2. Git 笔记 上传文件至github
  3. 2018 Multi-University Training Contest 6-oval-and-rectangle(hdu 6362)-题解
  4. 【译】Getting Started With Ethereum and Building a Basic Dapp — Part 2
  5. PAT_B_1095_Java(25分)
  6. 【今日CV 计算机视觉论文速览 第127期】Fri, 7 Jun 2019
  7. 使用static代码块实现线程安全的单例设计模式
  8. html dw map,DW十六 map标签
  9. 安全的API接口解决方案
  10. PowerDesigner 11 一些小技巧
  11. WebRTC之RFC协议下载(八)
  12. 浅谈prometheus(普罗米修斯) client golang
  13. logback.xml和日志输入格式说明
  14. 使用WinDbg Preview解决Win10系统蓝屏问题
  15. mysql登录其他电脑_如何连接另一台电脑的mysql数据库
  16. Android-如何自定义crash处理器
  17. 解决oracle导出dmp时 904错误
  18. 记一次服务器被植入木马/病毒:kdevtmpfsi
  19. js实现局部打印,并处理浏览器提示Avoid using document.write()导致无法打印问题
  20. 现有的人脸数据库介绍及下载链接

热门文章

  1. i7 7500u java 开发_Intel Core i7-7500U性能跑和评测 | ZMMOO
  2. Binwalk工具的安装
  3. PHP调用Python和PHP向Python发送数据
  4. Zookeeper(超级无敌认真好用,万字收藏篇!!!!)
  5. json串消除反斜杠\的方法
  6. 解决连网了浏览器出现的问题,诊断策略服务和DNS服务器未响应
  7. linux amd显卡驱动画面撕裂,从此告别画面撕裂 AMD-FreeSync技术解析
  8. 【百度地图】路书轨迹显示
  9. 连续时间动态主题模型(Continuous Time Dynamic Topic Models, cDTM)
  10. [聊聊] (解读)5模13频、5模17频、全网通、双4G,到底是什么?