T1 words

题目大意: bzoj 4567

题解链接

考试代码:

(如果不重建树的话会出锅 例子:

3.13 模拟赛

其中加粗的边为有$end$标记的节点,若不重建树,则左边$a$的$sz$为4,右边为3会先走右边

实际上应该先走左边(man太惨了。

View Code

 

T2 tree

题目大意:bzoj 4817

一棵树 支持三种操作:

1 x:把点x到根节点的路径上所有的点染上一种没有用过的新颜色

2 x y:求x到y的路径的权值

3 x:在以x为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值

思路:

(之前看wls做过这道题,对大致思路有一个了解,当时感觉好神啊

维护每个点到根的路径的权值

这样两个询问的答案分别为$val_a+val_b-2*val_{lca}+1$与子树中的最大值,用线段树可以很方便的维护

对于修改,发现这个过程与$LCT$的$access$很像

使用$LCT$来维护修改,即对于修改,$access$该点,并在过程中修改

找到两个部分内最浅的点,然后用线段树一个$+1$一个$-1$修改即可非常完美的解决

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<queue>
  8 #include<vector>
  9 #include<set>
 10 #include<map>
 11 #define ll long long
 12 #define rep(i,s,t) for(int i=(s),i##end=(t);i<=i##end;++i)
 13 #define dwn(i,s,t) for(int i=(s),i##end=(t);i>=i##end;--i)
 14 #define ren for(int i=fst[x];i;i=nxt[i])
 15 #define MAXN 100100
 16 using namespace std;
 17 inline int read()
 18 {
 19     int x=0,f=1;char ch=getchar();
 20     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
 21     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
 22     return x*f;
 23 }
 24 int n,m,fst[MAXN],nxt[MAXN<<1],to[MAXN<<1],cnt,dep[MAXN];
 25 int fa[MAXN],sz[MAXN],hvs[MAXN],tot,bl[MAXN],in[MAXN];
 26 int mx[MAXN<<2],tag[MAXN<<2];
 27 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
 28 void dfs(int x,int pa)
 29 {
 30     fa[x]=pa,sz[x]=1;
 31     ren if(to[i]^pa) dep[to[i]]=dep[x]+1,dfs(to[i],x),
 32         sz[x]+=sz[to[i]],hvs[x]=sz[to[i]]>sz[hvs[x]]?to[i]:hvs[x];
 33 }
 34 void Dfs(int x,int anc)
 35 {
 36     bl[x]=anc,in[x]=++tot;if(!hvs[x]) return ;
 37     Dfs(hvs[x],anc);ren if(to[i]^fa[x]&&to[i]^hvs[x]) Dfs(to[i],to[i]);
 38 }
 39 int lca(int a,int b)
 40 {
 41     for(;bl[a]!=bl[b];a=fa[bl[a]])
 42         if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
 43     return in[a]<in[b]?a:b;
 44 }
 45 void pshd(int k)
 46 {
 47     mx[k<<1]+=tag[k],mx[k<<1|1]+=tag[k];
 48     tag[k<<1]+=tag[k],tag[k<<1|1]+=tag[k],tag[k]=0;
 49 }
 50 void mdf(int k,int l,int r,int a,int b,int x)
 51 {
 52     if(l==a&&r==b) {tag[k]+=x,mx[k]+=x;return ;}int mid=l+r>>1;
 53     if(tag[k]) pshd(k);
 54     if(b<=mid) mdf(k<<1,l,mid,a,b,x);
 55     else if(a>mid) mdf(k<<1|1,mid+1,r,a,b,x);
 56     else {mdf(k<<1,l,mid,a,mid,x);mdf(k<<1|1,mid+1,r,mid+1,b,x);}
 57     mx[k]=max(mx[k<<1],mx[k<<1|1]);
 58 }
 59 int query(int k,int l,int r,int a,int b)
 60 {
 61     if(l==a&&r==b) return mx[k];int mid=l+r>>1;
 62     if(tag[k]) pshd(k);
 63     if(b<=mid) return query(k<<1,l,mid,a,b);
 64     else if(a>mid) return query(k<<1|1,mid+1,r,a,b);
 65     else return max(query(k<<1,l,mid,a,mid),query(k<<1|1,mid+1,r,mid+1,b));
 66 }
 67 namespace lct
 68 {
 69     int ch[MAXN][2],tag[MAXN],fa[MAXN];
 70     int which(int x) {return ch[fa[x]][1]==x;}
 71     int isroot(int x) {return ch[fa[x]][1]!=x&&ch[fa[x]][0]!=x;}
 72     void rotate(int x)
 73     {
 74         int f=fa[x],ff=fa[f],k=which(x);
 75         if(!isroot(f)) ch[ff][ch[ff][1]==f]=x;fa[x]=ff;
 76         ch[f][k]=ch[x][k^1],fa[ch[x][k^1]]=f,ch[x][k^1]=f,fa[f]=x;
 77     }
 78     void splay(int x)
 79     {
 80         for(int f;!isroot(x);rotate(x))
 81             if(!isroot(f=fa[x])) rotate(which(x)==which(f)?f:x);
 82     }
 83     int find(int x) {while(ch[x][0]) x=ch[x][0];return x;}
 84     void access(int x)
 85     {
 86         for(int t=0,tmp;x;t=x,x=fa[x])
 87         {
 88             splay(x);
 89             if(ch[x][1]){tmp=find(ch[x][1]);mdf(1,1,n,in[tmp],in[tmp]+sz[tmp]-1,1);}
 90             ch[x][1]=t;if(t){tmp=find(t);mdf(1,1,n,in[tmp],in[tmp]+sz[tmp]-1,-1);}
 91         }
 92     }
 93 };
 94 int main()
 95 {
 96     n=read(),m=read();int a,b,c;rep(i,2,n) a=read(),b=read(),add(a,b),add(b,a);
 97     dep[1]=1;dfs(1,0);Dfs(1,1);rep(i,1,n) mdf(1,1,n,in[i],in[i],dep[i]),lct::fa[i]=fa[i];
 98     while(m--)
 99     {
100         c=read(),a=read();
101         if(c==1) lct::access(a);
102         else if(c==2)
103         {
104             b=read(),c=lca(a,b);
105             printf("%d\n",query(1,1,n,in[a],in[a])+query(1,1,n,in[b],in[b])-2*query(1,1,n,in[c],in[c])+1);
106         }
107         else printf("%d\n",query(1,1,n,in[a],in[a]+sz[a]-1));
108     }
109 }
View Code

相关文章:

  • 2021-12-15
  • 2021-06-15
  • 2021-04-02
  • 2021-08-12
  • 2021-12-25
  • 2021-05-27
  • 2021-09-06
  • 2022-01-20
猜你喜欢
  • 2021-06-06
  • 2021-08-19
  • 2022-12-23
  • 2021-04-18
  • 2021-07-06
  • 2021-12-28
相关资源
相似解决方案