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] 轻重边的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ3669:[NOI2014]魔法森林——题解

Luogu ????????????????????? ([NOI2014]?????????????????????)

luogu P2254 [NOI2005]瑰丽华尔兹

NOI2015 程序自动分析(luogu p1955)

NOI2002 银河英雄传说(luogu p1196)

luogu2114 [NOI2014]起床困难综合症