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 }

 

posted @ 2021-09-05 09:48  上官书房  阅读(26)  评论(0)    收藏  举报