数链剖分(Tree)
Posted letlifestop
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数链剖分(Tree)相关的知识,希望对你有一定的参考价值。
题目链接:https://cn.vjudge.net/contest/279350#problem/D
题目大意:操作,单点查询,区间取反,询问区间最大值。
AC代码:
1 #include<iostream> 2 #include<cmath> 3 #include<stack> 4 #include<queue> 5 #include<stdio.h> 6 #include<string> 7 #include<cstring> 8 #include<algorithm> 9 using namespace std; 10 # define inf 0x3f3f3f3f 11 # define ll long long 12 # define lson l,m,rt<<1 13 # define rson m+1,r,rt<<1|1 14 const int maxn = 3e5+100; 15 int sto[maxn],head[maxn],edgnum,dfsnum,depth[maxn]; 16 int son[maxn],father[maxn],Size[maxn],ord[maxn],cost[maxn],top[maxn]; 17 int maxtree[maxn<<2],mintree[maxn<<2],maxx,lazy[maxn<<2]; 18 struct node 19 { 20 int fr; 21 int to; 22 int nex; 23 int cost; 24 } edge[maxn],po[maxn]; 25 void addedge(int fr,int to) 26 { 27 edge[edgnum].fr=fr; 28 edge[edgnum].to=to; 29 edge[edgnum].nex=head[fr]; 30 head[fr]=edgnum++; 31 } 32 void dfs1(int fr,int rt,int dep) 33 { 34 father[fr]=rt; 35 Size[fr]=1; 36 son[fr]=-1; 37 depth[fr]=dep; 38 for(int i=head[fr]; i!=-1; i=edge[i].nex) 39 { 40 int to=edge[i].to; 41 if(to==rt) 42 continue; 43 dfs1(to,fr,dep+1); 44 Size[fr]+=Size[to]; 45 if(son[to]==-1||(Size[son[fr]]<Size[to])) 46 { 47 son[fr]=to; 48 } 49 } 50 } 51 void dfs2(int fr,int rt) 52 { 53 ord[fr]=++dfsnum; 54 cost[ord[fr]]=sto[fr]; 55 top[fr]=rt; 56 if(son[fr]!=-1) 57 dfs2(son[fr],rt); 58 for(int i=head[fr]; i!=-1; i=edge[i].nex) 59 { 60 int u=edge[i].to; 61 if(son[fr]!=u&&father[fr]!=u) 62 { 63 dfs2(u,u); 64 } 65 } 66 } 67 void up(int rt) 68 { 69 maxtree[rt]=max(maxtree[rt<<1],maxtree[rt<<1|1]); 70 mintree[rt]=min(mintree[rt<<1],mintree[rt<<1|1]); 71 } 72 void buildtree(int l,int r,int rt) 73 { 74 if(l==r) 75 { 76 maxtree[rt]=sto[l]; 77 mintree[rt]=sto[l]; 78 lazy[rt]++; 79 return ; 80 } 81 int m=(l+r)>>1; 82 buildtree(lson); 83 buildtree(rson); 84 up(rt); 85 } 86 void change(int rt) 87 { 88 int tmp=mintree[rt]; 89 mintree[rt]=-maxtree[rt]; 90 maxtree[rt]=-tmp; 91 } 92 void down(int rt) 93 { 94 if(!lazy[rt]) 95 return ; 96 lazy[rt<<1]^=1; 97 lazy[rt<<1|1]^=1; 98 change(rt<<1); 99 change(rt<<1|1); 100 lazy[rt]^=1; 101 } 102 void query(int l,int r,int rt,int L,int R) 103 { 104 if(L<=l&&R>=r) 105 { 106 maxx=max(maxx,maxtree[rt]); 107 return ; 108 } 109 down(rt); 110 int m=(l+r)>>1; 111 if(L<=m) 112 query(lson,L,R); 113 if(R>m) 114 query(rson,L,R); 115 up(rt); 116 } 117 void update1(int l,int r,int rt,int pos,int p) 118 { 119 if(l==r) 120 { 121 maxtree[rt]=p; 122 mintree[rt]=p; 123 return ; 124 } 125 down(rt); 126 int m=(l+r)>>1; 127 if(pos<=m) 128 update1(lson,pos,p); 129 if(pos>m) 130 update1(rson,pos,p); 131 up(rt); 132 } 133 void update2(int l,int r,int rt,int L,int R) 134 { 135 if(L<=l&&R>=r) 136 { 137 change(rt); 138 lazy[rt]^=1; 139 return ; 140 } 141 down(rt); 142 int m=(l+r)>>1; 143 if(L<=m) 144 update2(lson,L,R); 145 if(R>m) 146 update2(rson,L,R); 147 up(rt); 148 } 149 void Query(int n,int x,int y) 150 { 151 maxx=-inf; 152 int tx=top[x],ty=top[y]; 153 while(tx!=ty) 154 { 155 if(depth[tx]<depth[ty]) 156 { 157 swap(tx,ty); 158 swap(x,y); 159 } 160 query(1,n,1,ord[tx],ord[x]); 161 x=father[tx],tx=top[x]; 162 } 163 if(depth[x]<depth[y]) 164 { 165 swap(x,y); 166 } 167 query(1,n,1,ord[y]+1,ord[x]); 168 } 169 void Update(int n,int x,int y) 170 { 171 int tx=top[x],ty=top[y]; 172 while(tx!=ty) 173 { 174 if(depth[tx]<depth[ty]) 175 { 176 swap(tx,ty); 177 swap(x,y); 178 } 179 update2(1,n,1,ord[tx],ord[x]); 180 x=father[tx],tx=top[x]; 181 } 182 if(depth[x]<depth[y]) 183 { 184 swap(x,y); 185 } 186 update2(1,n,1,ord[y]+1,ord[x]); 187 } 188 int main() 189 { 190 int T; 191 scanf("%d",&T); 192 while(T--) 193 { 194 dfsnum=edgnum=0; 195 int n,q,s; 196 scanf("%d",&n); 197 int t1,t2,t3; 198 memset(maxtree,0,sizeof(maxtree)); 199 memset(mintree,0,sizeof(mintree)); 200 memset(lazy,0,sizeof(lazy)); 201 memset(head,-1,sizeof(head)); 202 for(int i=1; i<=n-1; i++) 203 { 204 scanf("%d %d %d",&t1,&t2,&t3); 205 addedge(t1,t2); 206 addedge(t2,t1); 207 po[i].fr=t1; 208 po[i].to=t2; 209 po[i].cost=t3; 210 } 211 dfs1(1,-1,1); 212 dfs2(1,1); 213 for(int i=1; i<=n-1; i++) 214 { 215 t1=depth[po[i].fr]; 216 t2=depth[po[i].to]; 217 if(t1>t2) 218 { 219 swap(po[i].fr,po[i].to); 220 } 221 update1(1,n,1,ord[po[i].to],po[i].cost); 222 } 223 char str[10]; 224 while(~scanf("%s",str)) 225 { 226 if(str[0]==‘D‘) 227 break; 228 else if(str[0]==‘Q‘) 229 { 230 scanf("%d %d",&t1,&t2); 231 Query(n,t1,t2); 232 printf("%d ",maxx); 233 } 234 else if(str[0]==‘C‘) 235 { 236 scanf("%d %d",&t1,&t2); 237 update1(1,n,1,ord[po[t1].to],t2); 238 } 239 else if(str[0]==‘N‘) 240 { 241 scanf("%d %d",&t1,&t2); 242 Update(n,t1,t2); 243 } 244 } 245 } 246 return 0; 247 }
以上是关于数链剖分(Tree)的主要内容,如果未能解决你的问题,请参考以下文章