hdu5390 tree

  先求出dfs序,然后建立线段树,线段树每个节点套一个set。

  修改操作只需要改被子树区间完全覆盖的线段树节点,将其节点中set的原来的值删除,加入新值。

  询问操作查询单点到根的所有节点上的set中与查询值异或起来最大的那个。

  查询set中的数与x异或的最大值,可以从高位到低位枚举二进制位,根据x的二进制位,查询一些set中数值的存在情况,例如加入x的二进制第y位为1,那么如果set中存在第y位为0的数字,明显可以使得答案更大。下面代码中这段的代码类似于二分。

  时间复杂度O(nlogn^3)

  

  代码

  1 #include<cstdio>
  2 #include<set>
  3 #include<algorithm>
  4 #include<cstring>
  5 #define N 500010
  6 using namespace std;
  7 int n,m,i,a,b,typ;
  8 int dp,p[N],pre[N],tt[N];
  9 int tot,L[N],R[N],l[N],r[N],v[N],stack[N],deep,flag;
 10 multiset<int> Set[N];
 11 void link(int x,int y)
 12 {
 13     dp++;pre[dp]=p[x];p[x]=dp;tt[dp]=y;
 14 }
 15 void dfs()
 16 {
 17     int i;
 18     while (deep)
 19     {
 20         if (L[stack[deep]]==0)
 21         {
 22             tot++;
 23             L[stack[deep]]=tot;
 24         }
 25         if (p[stack[deep]])
 26         {
 27             i=p[stack[deep]];
 28             deep++;stack[deep]=tt[i];
 29             p[stack[deep-1]]=pre[i];
 30         }
 31         else
 32         {
 33             R[stack[deep]]=tot;
 34             deep--;
 35         }
 36     }
 37 }
 38 void build(int x,int a,int b)
 39 {
 40     int m;
 41     l[x]=a;r[x]=b;
 42     Set[x].clear();
 43     Set[x].insert(-1);
 44     Set[x].insert(1<<30);
 45     if (b-a>1)
 46     {
 47         m=(a+b)>>1;
 48         build(2*x,a,m);
 49         build(2*x+1,m,b);
 50     }
 51 }
 52 void change(int x,int a,int b,int c,int d)
 53 {
 54     if ((a<=l[x])&&(r[x]<=b))
 55     {
 56         Set[x].insert(d);
 57         if (flag)
 58         Set[x].erase(c);
 59         return;
 60     }
 61     int m=(l[x]+r[x])>>1;
 62     if (a<m) change(2*x,a,b,c,d);
 63     if (m<b) change(2*x+1,a,b,c,d);
 64 }
 65 int Q(int x,int y)
 66 {
 67     int l,r,m,p,q;
 68     if (Set[x].size()==2) return 0;
 69     l=0;r=(1<<30)-1;
 70     while (l!=r)
 71     {
 72         m=(l+r)>>1;
 73         multiset<int>::iterator it=Set[x].upper_bound(m);
 74         p=*it;
 75         q=*(--it);
 76         if (p>r)
 77             r=m;
 78         else
 79         if (q<l)
 80             l=m+1;
 81         else
 82         {
 83             if ((l^y)>((m+1)^y))
 84             r=m;
 85             else
 86             l=m+1;
 87         }
 88     }
 89     return l^y;
 90 }
 91 int query(int x,int a,int b,int c)
 92 {
 93     int ans=Q(x,c);
 94     if ((a<=l[x])&&(r[x]<=b))
 95     return ans;
 96     int m=(l[x]+r[x])>>1;
 97     if (a<m) ans=max(ans,query(2*x,a,b,c));
 98     if (m<b) ans=max(ans,query(2*x+1,a,b,c));
 99     return ans;
100 }
101 int main()
102 {
103     int test;
104     scanf("%d",&test);
105     while (test--)
106     {
107     scanf("%d%d",&n,&m);
108     dp=0;
109     for (i=1;i<=n;i++)
110     {
111         L[i]=0;
112         p[i]=0;
113     }
114     for (i=2;i<=n;i++)
115     {
116         scanf("%d",&a);
117         link(a,i);
118     }
119     tot=0;
120     deep=1;stack[1]=1;
121     dfs();
122
123     build(1,0,n);
124     flag=0;
125     for (i=1;i<=n;i++)
126     {
127         scanf("%d",&v[i]);
128         change(1,L[i]-1,R[i],0,v[i]);
129     }
130     flag=1;
131     for (i=1;i<=m;i++)
132     {
133         scanf("%d",&typ);
134         if (typ==0)
135         {
136             scanf("%d%d",&a,&b);
137             change(1,L[a]-1,R[a],v[a],b);
138             v[a]=b;
139         }
140         else
141         {
142             scanf("%d",&a);
143             printf("%d\n",query(1,L[a]-1,L[a],v[a]));
144         }
145     }
146     }
147 }
时间: 2024-10-18 17:26:45

hdu5390 tree的相关文章

easyui js取消选中 Tree 指定节点

取消所有选中 var rootNodes = treeObject.tree('getRoots'); for ( var i = 0; i < rootNodes.length; i++) { var node = treeObject.tree('find', rootNodes[i].id); treeObject.tree('uncheck', node.target); }

Maximum Depth of Binary Tree

这道题为简单题 题目: Given a binary tree, find its maximum depth.The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 思路: 我是用递归做的,当然也可以用深搜和广搜,递归的话就是比较左右子树的深度然后返回 代码: 1 # Definition for a binary tre

538. Convert BST to Greater Tree 二叉搜索树转换为更大树

Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST. Example: Input: The root of a Binary Search Tree like thi

SPOJ375 Query on a tree

https://vjudge.net/problem/SPOJ-QTREE 题意: 一棵树,每条边有个权值 两种操作 一个修改每条边权值 一个询问两点之间这一条链的最大边权 点数<=10000 多组测试数据,case<=20 Example Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3 #include<cstdio> #include<iostream> #include&

POJ 1741 Tree(树的点分治,入门题)

Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 21357   Accepted: 7006 Description Give a tree with n vertices,each edge has a length(positive integer less than 1001).Define dist(u,v)=The min distance between node u and v.Give an in

命令-tree

tree命令 tree - list contents of directories in a tree-like format. 显示目录的层级结构: tree 命令英文理解为树的意思,其功能是创建文件列表,将目录所有文件以树状的形式列出来.linux中的tree命令默认并不会安装,所以需要通过yum install tree -y来安装此命令. [SYNOPSIS] tree [options] [directory] [OPTIONS] -L level:指定要显示的层级: -d:仅列出目

[LeetCode] Find Mode in Binary Search Tree 找二分搜索数的众数

Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred element) in the given BST. Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than or equal to the nod

226反转二叉树 Invert Binary Tree

Invert a binary tree. 4 / 2 7 / \ / 1 3 6 9 to 4 / 7 2 / \ / 9 6 3 1 Trivia:This problem was inspired by this original tweet by Max Howell: Google: 90% of our engineers use the software you wrote (Homebrew), but you can't invert a binary tree on a wh

[hihoCoder#1381]Little Y&#39;s Tree

[hihoCoder#1381]Little Y's Tree 试题描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每次小J会删掉这个树中的k条边,这棵树被分成k+1个连通块.小J想知道每个连通块中最远点对距离的和. 这里的询问是互相独立的,即每次都是在小Y的原树上进行操作. 输入 第一行一个整数n,接下来n-1行每行三个整数u,v,w,其中第i行表示第i条边边权为wi,连接了ui,vi两点. 接下来一行一个整数q,表示有q组询问. 对于每组询问,第一行一个正整数k,接下来一