Luogu P1505 [国家集训队]旅游(树链剖分)
题目链接:https://www.luogu.com.cn/problem/P1505
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=5e5+11,M=N<<1,Tree_Sz=3e6+11,inf=1<<29; 4 int n,m,a[N]; 5 int frm[M],to[M],nxt[M],dt[M],edge,head[N]; 6 int fa[N],dep[N],siz[N],son[N]; 7 int seg[N],rev[N],tot,top[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 16 inline void addedge(int x,int y,int z) { 17 ++edge,frm[edge]=x,to[edge]=y,nxt[edge]=head[x],dt[edge]=z,head[x]=edge; 18 ++edge,frm[edge]=y,to[edge]=x,nxt[edge]=head[y],dt[edge]=z,head[y]=edge; 19 } 20 21 void dfs1(int d,int f,int fr) { 22 fa[d]=f,dep[d]=dep[f]+1,siz[d]=1,a[d]=dt[fr]; 23 for(int i=head[d],u;i;i=nxt[i]) { 24 u=to[i]; 25 if(u==f) continue; 26 dfs1(u,d,i); 27 siz[d]+=siz[u]; 28 if(siz[u]>siz[son[d]]) son[d]=u; 29 } 30 } 31 32 void dfs2(int d) { 33 if(son[d]) { 34 int u=son[d]; 35 seg[u]=++tot,rev[tot]=u,top[u]=top[d]; 36 dfs2(u); 37 } 38 for(int i=head[d],u;i;i=nxt[i]) { 39 u=to[i]; 40 if(u==fa[d] || u==son[d]) continue; 41 seg[u]=++tot,rev[tot]=u,top[u]=u; 42 dfs2(u); 43 } 44 } 45 46 inline void print_test() { 47 for(int i=1;i<=n;++i) printf("%d ",seg[i]); puts(""); 48 for(int i=1;i<=n;++i) printf("%d ",rev[i]); puts(""); 49 for(int i=1;i<=n;++i) printf("%d ",top[i]); puts(""); 50 for(int i=1;i<=n;++i) printf("%d ",a[i]); puts(""); 51 } 52 53 struct Segment { 54 struct Node { 55 int sum,maxx,minn,tag; 56 Node() { sum=tag=0,maxx=-inf,minn=inf; } 57 }t[Tree_Sz]; 58 inline void Pushup(int d) { 59 // t[d]=t[d<<1]+t[d<<1|1]; 60 t[d].sum=t[d<<1].sum+t[d<<1|1].sum; 61 t[d].maxx=max(t[d<<1].maxx,t[d<<1|1].maxx); 62 t[d].minn=min(t[d<<1].minn,t[d<<1|1].minn); 63 } 64 inline void Pushdown(int d,int l,int r) { 65 if(!t[d].tag) return ; 66 t[d<<1].tag^=t[d].tag; 67 t[d<<1|1].tag^=t[d].tag; 68 t[d<<1].sum=-t[d<<1].sum; 69 t[d<<1|1].sum=-t[d<<1|1].sum; 70 swap(t[d<<1].maxx,t[d<<1].minn); 71 t[d<<1].maxx=-t[d<<1].maxx; 72 t[d<<1].minn=-t[d<<1].minn; 73 swap(t[d<<1|1].minn,t[d<<1|1].maxx); 74 t[d<<1|1].maxx=-t[d<<1|1].maxx; 75 t[d<<1|1].minn=-t[d<<1|1].minn; 76 t[d].tag=0; 77 } 78 void build(int d,int l,int r) { 79 if(l==r) { t[d].sum=t[d].maxx=t[d].minn=a[rev[l]]; return ; } 80 int mid=(l+r)>>1; 81 build(d<<1,l,mid),build(d<<1|1,mid+1,r); 82 Pushup(d); 83 } 84 inline void Build() { build(1,2,n); } 85 void modify(int d,int l,int r,int x,int z) { 86 if(l==r) { 87 t[d].sum=z*(r-l+1),t[d].maxx=z,t[d].minn=z; 88 return ; 89 } 90 Pushdown(d,l,r); 91 int mid=(l+r)>>1; 92 if(x<=mid) modify(d<<1,l,mid,x,z); 93 else modify(d<<1|1,mid+1,r,x,z); 94 Pushup(d); 95 } 96 inline void Modify(int x,int z) { 97 x=(dep[frm[x]]>dep[to[x]])?frm[x]:to[x]; 98 // printf("Change: %d %d\n",x,z); 99 modify(1,2,n,seg[x],z); 100 } 101 void rever(int d,int l,int r,int x,int y) { 102 // if(x==1634 && y==1634) printf("%d %d %d\n",d,l,r); 103 if(x<=l && r<=y) { 104 t[d].sum=-t[d].sum; 105 swap(t[d].maxx,t[d].minn); 106 t[d].maxx=-t[d].maxx; 107 t[d].minn=-t[d].minn; 108 t[d].tag^=1; 109 return ; 110 } 111 Pushdown(d,l,r); 112 int mid=(l+r)>>1; 113 if(x<=mid) rever(d<<1,l,mid,x,y); 114 if(y>=mid+1) rever(d<<1|1,mid+1,r,x,y); 115 Pushup(d); 116 // if(x==1634 && y==1634) printf("end: %d\n",d); 117 } 118 inline void Rever(int x,int y,int t) { 119 // if(x==1631 && y==1631) printf("%d %d %d %d\n",seg[x],seg[y],t,n); 120 rever(1,2,n,seg[x]+t,seg[y]); 121 } 122 Node query(int d,int l,int r,int x,int y) { 123 if(x<=l && r<=y) return t[d]; 124 Pushdown(d,l,r); 125 int mid=(l+r)>>1; Node res,tmp; 126 if(x<=mid) { 127 tmp=query(d<<1,l,mid,x,y); 128 res.sum+=tmp.sum,res.maxx=max(res.maxx,tmp.maxx),res.minn=min(res.minn,tmp.minn); 129 } 130 if(y>=mid+1) { 131 tmp=query(d<<1|1,mid+1,r,x,y); 132 res.sum+=tmp.sum,res.maxx=max(res.maxx,tmp.maxx),res.minn=min(res.minn,tmp.minn); 133 } 134 return res; 135 } 136 inline int Query(int x,int y,int op,int t) { 137 Node res; 138 res=query(1,2,n,seg[x]+t,seg[y]); 139 if(op==1) return res.sum; 140 else if(op==2) return res.maxx; 141 else return res.minn; 142 } 143 void search(int d,int l,int r) { 144 // printf("%d %d %d %d %d %d\n",d,l,r,t[d].sum,t[d].maxx,t[d].minn); 145 if(l==r) return ; 146 int mid=(l+r)>>1; 147 search(d<<1,l,mid),search(d<<1|1,mid+1,r); 148 } 149 }st; 150 151 inline void Reverse(int x,int y) { 152 // if(x==1631 && y==69) printf("awa\n"); 153 if(dep[x]<dep[y]) x^=y^=x^=y; 154 int fx=top[x],fy=top[y]; 155 while(fx!=fy) { 156 // if(x==1631 && y==69) printf("%d %d %d %d\n",x,y,fx,fy); 157 if(dep[fx]<dep[fy]) x^=y^=x^=y,fx^=fy^=fx^=fy; 158 st.Rever(fx,x,0); 159 // if(x==1631 && y==69) printf("qwq %d %d %d %d\n",x,fx,fa[fx],top[fa[fx]]); 160 x=fa[fx],fx=top[x]; 161 } 162 if(dep[x]>dep[y]) x^=y^=x^=y; 163 // printf("%d %d\n",x,y); 164 if(x!=y) st.Rever(x,y,1); 165 } 166 167 inline void Ask(int x,int y,int op) { 168 if(dep[x]<dep[y]) x^=y^=x^=y; 169 int fx=top[x],fy=top[y],res; 170 if(op==1) res=0; 171 else if(op==2) res=-inf; 172 else res=inf; 173 while(fx!=fy) { 174 if(dep[fx]<dep[fy]) x^=y^=x^=y,fx^=fy^=fx^=fy; 175 if(op==1) res+=st.Query(fx,x,1,0); 176 else if(op==2) res=max(res,st.Query(fx,x,2,0)); 177 else res=min(res,st.Query(fx,x,3,0)); 178 x=fa[fx],fx=top[x]; 179 } 180 if(dep[x]>dep[y]) x^=y^=x^=y; 181 if(x!=y) { 182 if(op==1) res+=st.Query(x,y,1,1); 183 else if(op==2) res=max(res,st.Query(x,y,2,1)); 184 else res=min(res,st.Query(x,y,3,1)); 185 } 186 printf("%d\n",res); 187 } 188 189 int main() 190 { 191 // freopen("P1505_1.in","r",stdin); 192 // freopen("P1505_1.ans","w",stdout); 193 n=re_ad(); edge=1; 194 for(int i=1,x,y,z;i<n;++i) x=re_ad(),y=re_ad(),z=re_ad(),addedge(x+1,y+1,z); 195 dfs1(1,0,0),tot=seg[1]=rev[1]=top[1]=1,dfs2(1),st.Build(); 196 // print_test(); 197 m=re_ad(); char str[11]; 198 for(int i=1,x,y;i<=m;++i) { 199 scanf("%s",str); x=re_ad(),y=re_ad(); 200 // printf("%c%c %d %d\n",str[0],str[1],x,y); 201 if(str[0]=='N') Reverse(x+1,y+1); 202 else if(str[0]=='C') st.Modify(x*2,y); 203 else if(str[0]=='S') Ask(x+1,y+1,1); 204 else Ask(x+1,y+1,(str[1]=='A')?2:3); 205 // st.search(1,2,n); puts(""); 206 } 207 return 0; 208 }