先求出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