博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu 4776 Ants(trie+优先队列)
阅读量:4321 次
发布时间:2019-06-06

本文共 1880 字,大约阅读时间需要 6 分钟。

题目链接:

题意:

给你一棵有n个节点的树,每条边有一个权值ai,现在定义两点直接的距离为路径上经过的边的异或和。

现在有m个询问,每次询问你第k长的路径是多少。

题解:

一开始我想二分+树分治+trie,发现只能做一个询问。- -!。

这里有一个优秀的做法,可以预处理出前k个答案。

首先,这里两点间的距离就是val[i]^val[j],val[i]表示根节点到i节点的异或和。

然后我们可以将所有的val插进trie,然后我们将每个节点都作为起点,将以该起点的最大路径放进优先队列。

显然当前第一大的肯定就是优先队列的top,然后我们将这个top 记录下来,并且pop掉。

然后将产生这个top的节点x得到以x为起点的第二大路径放进优先队列。并且重复操作。

这样就可以将前k个答案以60*n*logn的复杂度预处理出来,然后询问就可以O(1)了。

1 #include
2 #define F(i,a,b) for(int i=(a);i<=(b);++i) 3 #define mst(a,b) memset(a,b,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 7 const int N=2e5+7; 8 int n,m,g[N],v[N*2],nxt[N*2],ed; 9 ll w[N*2],val[N],z,ans[N];10 int ct,x,y,cnt[N*62],tr[N*62][2],tot;11 struct Node12 {13 int idx,k;14 ll val;15 Node(int a=0,int b=0,ll c=0):idx(a),k(b),val(c){}16 bool operator<(const Node &B)const{
return val
Q;19 20 void adg(int x,int y,ll z){v[++ed]=y,w[ed]=z,nxt[ed]=g[x],g[x]=ed;}21 22 void dfs(int x,ll va,int fa)23 {24 val[x]=va;25 for(int i=g[x];i;i=nxt[i])26 if(v[i]!=fa)dfs(v[i],va^w[i],x);27 }28 29 void ins(ll a,int x=1)30 {31 for(int i=60;i>=0;i--)32 {33 int w=(a>>i)&1;34 if(!tr[x][w])35 {36 cnt[++tot]=0,mst(tr[tot],0);37 tr[x][w]=tot;38 }39 x=tr[x][w],cnt[x]++;40 }41 }42 43 ll kth(ll a,int k,int x=1,int i=60)44 {45 if(i<0)return 0;46 int w=(a>>i)&1;47 if(tr[x][w^1]&&cnt[tr[x][w^1]]>=k)48 return (1ll*(w^1)<
n)continue;76 ll tp=kth(val[now.idx],now.k+1)^val[now.idx];77 Q.push(Node(now.idx,now.k+1,tp));78 }79 scanf("%d",&m);80 F(i,1,m)81 {82 scanf("%d",&x);83 printf("%lld\n",(x>ct||n==1)?-1:ans[x]);84 }85 }86 return 0;87 }
View Code

 

转载于:https://www.cnblogs.com/bin-gege/p/7652599.html

你可能感兴趣的文章
景安快运挂在磁盘-支持宝塔
查看>>
word中交叉引用不能更新的解决方法
查看>>
高性能HTTP加速器Varnish(概念篇)
查看>>
Linux 如何写makefile文件
查看>>
flutter_webview_plugin 无法加载网页的异常处理
查看>>
bloc控制读写文件
查看>>
微信小程序
查看>>
洛谷 P1059 明明的随机数
查看>>
window自动任务实现数据库定时备份
查看>>
Windows 7 Ultimate(旗舰版)SP1 32/64位官方原版下载(2011年5月12日更新版)
查看>>
javascript操作cookie
查看>>
深入理解HTTP协议(转)
查看>>
NHibernate讲解
查看>>
剑指offer-二叉树中和为某一值的路径
查看>>
spark算子
查看>>
(转)Linux服务器SNMP常用OID
查看>>
USB各种模式 解释
查看>>
数据访问-----ADO.NET 小结和练习
查看>>
Linux lsof详解
查看>>
子组件给父组件传数据
查看>>