Luogu P7735 [NOI2021] 轻重边
Posted 上官书房
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P7735 [NOI2021] 轻重边相关的知识,希望对你有一定的参考价值。
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e5+11,M=2e5+11,tree_Sz=5e5+11; 4 int T,n,m,colorcnt; 5 int to[M],nxt[M],edge,head[N]; 6 int fa[N],dep[N],sz[N],son[N]; 7 int top[N],cnt,seg[N],rev[N]; 8 9 inline int re_ad() { 10 char ch=getchar(); int x=0,f=1; 11 while(ch<\'0\' || ch>\'9\') { if(ch==\'-\') f=-1; ch=getchar(); } 12 while(\'0\'<=ch && ch<=\'9\') x=(x<<1)+(x<<3)+ch-\'0\',ch=getchar(); 13 return x*f; 14 } 15 struct Node { 16 int lc,rc,val,tag; 17 Node() { lc=rc=val=tag=0; } 18 }; 19 20 struct SegmentTree { 21 Node t[tree_Sz]; 22 inline void tree_clear() { 23 for(int i=1;i<=n*3;++i) t[i].lc=t[i].rc=t[i].val=t[i].tag=0; 24 } 25 inline void pushup(int d) { 26 t[d].val=t[d<<1].val+t[d<<1|1].val; 27 t[d].lc=t[d<<1].lc,t[d].rc=t[d<<1|1].rc; 28 t[d].val+=(t[d<<1].rc==t[d<<1|1].lc); 29 } 30 inline void pushdown(int d,int l,int r) { 31 int &tg=t[d].tag; 32 if(!tg) return ; 33 t[d<<1].tag=t[d<<1|1].tag=tg; 34 int mid=(l+r)>>1; 35 t[d<<1].val=mid-l; 36 t[d<<1|1].val=r-mid-1; 37 t[d<<1].lc=t[d<<1].rc=t[d<<1|1].lc=t[d<<1|1].rc=tg; 38 tg=0; 39 } 40 void build(int d,int l,int r) { 41 if(l==r) { 42 t[d].lc=t[d].rc=-l; 43 t[d].val=0; 44 return ; 45 } 46 int mid=(l+r)>>1; 47 build(d<<1,l,mid); 48 build(d<<1|1,mid+1,r); 49 pushup(d); 50 } 51 inline void Build() { 52 build(1,1,n); 53 } 54 void modify(int d,int l,int r,int x,int y,int z) { 55 if(x<=l && r<=y) { 56 t[d].lc=t[d].rc=t[d].tag=z; 57 t[d].val=r-l; 58 return ; 59 } 60 pushdown(d,l,r); 61 int mid=(l+r)>>1; 62 if(x<=mid) modify(d<<1,l,mid,x,y,z); 63 if(y>=mid+1) modify(d<<1|1,mid+1,r,x,y,z); 64 pushup(d); 65 } 66 inline void Modify(int x,int y,int z) { 67 modify(1,1,n,x,y,z); 68 } 69 Node query(int d,int l,int r,int x,int y) { 70 if(x<=l && r<=y) { 71 return t[d]; 72 } 73 pushdown(d,l,r); 74 int mid=(l+r)>>1; 75 Node res,ln,rn; 76 if(x<=mid) { 77 ln=query(d<<1,l,mid,x,y); 78 res.val+=ln.val; 79 res.lc=ln.lc; 80 if(y<mid+1) res.rc=ln.rc; 81 } 82 if(y>=mid+1) { 83 rn=query(d<<1|1,mid+1,r,x,y); 84 res.val+=rn.val; 85 res.rc=rn.rc; 86 if(x>mid) res.lc=rn.lc; 87 } 88 if(t[d<<1].rc==t[d<<1|1].lc && x<=mid && y>=mid+1) ++res.val; 89 return res; 90 } 91 inline Node Query(int x,int y) { 92 return query(1,1,n,x,y); 93 } 94 void search(int d,int l,int r) { 95 printf("%d %d %d %d %d %d %d\\n",d,l,r,t[d].lc,t[d].rc,t[d].val,t[d].tag); 96 if(l==r) return ; 97 int mid=(l+r)>>1; 98 search(d<<1,l,mid),search(d<<1|1,mid+1,r); 99 } 100 }st; 101 102 inline void addedge(int x,int y) { 103 ++edge,to[edge]=y,nxt[edge]=head[x],head[x]=edge; 104 ++edge,to[edge]=x,nxt[edge]=head[y],head[y]=edge; 105 } 106 107 inline void init() { 108 edge=1,cnt=0; 109 colorcnt=0; 110 memset(to,0,sizeof(to)); 111 memset(nxt,0,sizeof(nxt)); 112 memset(head,0,sizeof(head)); 113 memset(fa,0,sizeof(fa)); 114 memset(dep,0,sizeof(dep)); 115 memset(sz,0,sizeof(sz)); 116 memset(son,0,sizeof(son)); 117 memset(top,0,sizeof(top)); 118 memset(seg,0,sizeof(seg)); 119 memset(rev,0,sizeof(rev)); 120 st.tree_clear(); 121 } 122 123 void dfs1(int d,int f) { 124 fa[d]=f,dep[d]=dep[f]+1,++sz[d]; 125 int maxx=0; 126 for(int i=head[d];i;i=nxt[i]) { 127 int u=to[i]; 128 if(u==f) continue; 129 dfs1(u,d); 130 sz[d]+=sz[u]; 131 if(sz[u]>maxx) maxx=sz[u],son[d]=u; 132 } 133 } 134 135 void dfs2(int d) { 136 if(son[d]) { 137 int u=son[d]; 138 seg[u]=++cnt,rev[cnt]=u,top[u]=top[d]; 139 dfs2(u); 140 } 141 for(int i=head[d];i;i=nxt[i]) { 142 int u=to[i]; 143 if(u==fa[d] || u==son[d]) continue; 144 seg[u]=++cnt,rev[cnt]=u,top[u]=u; 145 dfs2(u); 146 } 147 } 148 149 inline void print_test() { 150 for(int i=0;i<=n;++i) cout<<setw(3)<<i; puts(""); 151 for(int i=0;i<=n;++i) cout<<setw(3)<<fa[i]; puts(""); 152 for(int i=0;i<=n;++i) cout<<setw(3)<<dep[i]; puts(""); 153 for(int i=0;i<=n;++i) cout<<setw(3)<<sz[i]; puts(""); 154 for(int i=0;i<=n;++i) cout<<setw(3)<<son[i]; puts(""); 155 for(int i=0;i<=n;++i) cout<<setw(3)<<top[i]; puts(""); 156 for(int i=0;i<=n;++i) cout<<setw(3)<<seg[i]; puts(""); 157 for(int i=0;i<=n;++i) cout<<setw(3)<<rev[i]; puts(""); 158 st.search(1,1,n); 159 } 160 161 inline void Update(int x,int y) { 162 int z=++colorcnt; 163 int fx=top[x],fy=top[y]; 164 while(fx!=fy) { 165 if(dep[fx]<dep[fy]) x^=y^=x^=y,fx^=fy^=fx^=fy; 166 st.Modify(seg[fx],seg[x],z); 167 x=fa[fx],fx=top[x]; 168 } 169 if(dep[x]>dep[y]) x^=y^=x^=y; 170 st.Modify(seg[x],seg[y],z); 171 } 172 173 inline void Ask(int x,int y) { 174 // if(x==6 && y==5) 175 // n+=0; 176 int res=0,lstx=0,lsty=0; 177 int fx=top[x],fy=top[y]; 178 Node tmp; 179 while(fx!=fy) { 180 if(dep[fx]>dep[fy]) { 181 tmp=st.Query(seg[fx],seg[x]); 182 res+=tmp.val; 183 x=fa[fx],fx=top[x]; 184 if(lstx) res+=(tmp.rc==lstx); 185 lstx=tmp.lc; 186 } 187 else { 188 tmp=st.Query(seg[fy],seg[y]); 189 res+=tmp.val; 190 y=fa[fy],fy=top[y]; 191 if(lsty) res+=(tmp.rc==lsty); 192 lsty=tmp.lc; 193 } 194 } 195 if(dep[x]<dep[y]) { 196 tmp=st.Query(seg[x],seg[y]); 197 res+=tmp.val; 198 if(lstx) res+=(tmp.lc==lstx); 199 if(lsty) res+=(tmp.rc==lsty); 200 } 201 else { 202 tmp=st.Query(seg[y],seg[x]); 203 res+=tmp.val; 204 if(lstx) res+=(tmp.rc==lstx); 205 if(lsty) res+=(tmp.lc==lsty); 206 } 207 printf("%d\\n",res); 208 } 209 210 int main() 211 { 212 // freopen("7735.in","r",stdin); 213 // freopen("7735.out","w",stdout); 214 int op,x,y; 215 T=re_ad(); 216 while(T--) { 217 n=re_ad(),m=re_ad(); 218 init(); 219 for(int i=1;i<=n-1;++i) x=re_ad(),y=re_ad(),addedge(x,y); 220 dfs1(1,0); 221 cnt=top[1]=seg[1]=rev[1]=1; 222 dfs2(1); 223 st.Build(); 224 225 // print_test(); 226 227 for(int i=1;i<=m;++i) { 228 op=re_ad(),x=re_ad(),y=re_ad(); 229 (op==1) ? Update(x,y) : Ask(x,y); 230 } 231 } 232 return 0; 233 }
以上是关于Luogu P7735 [NOI2021] 轻重边的主要内容,如果未能解决你的问题,请参考以下文章
Luogu ????????????????????? ([NOI2014]?????????????????????)