洛谷P1505 [国家集训队]旅游(树剖+线段树)

传送门

这该死的码农题……

把每一条边变为它连接的两个点中深度较浅的那一个,然后就是一堆单点修改/路径查询,不讲了

这里就讲一下怎么搞路径取反,只要打一个标记就好了,然后把区间和取反,最大最小值交换然后再取反

单点修改的时候忘记pushdown结果调了好久……

  1 //minamoto
  2 #include<bits/stdc++.h>
  3 #define inf 0x3f3f3f3f
  4 using namespace std;
  5 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
  6 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
  7 inline int read(){
  8     #define num ch-'0'
  9     char ch;bool flag=0;int res;
 10     while(!isdigit(ch=getchar()))
 11     (ch=='-')&&(flag=true);
 12     for(res=num;isdigit(ch=getchar());res=res*10+num);
 13     (flag)&&(res=-res);
 14     #undef num
 15     return res;
 16 }
 17 char sr[1<<21],z[20];int K=-1,Z;
 18 inline void Ot(){fwrite(sr,1,K+1,stdout),K=-1;}
 19 inline void print(int x){
 20     if(K>1<<20)Ot();if(x<0)sr[++K]=45,x=-x;
 21     while(z[++Z]=x%10+48,x/=10);
 22     while(sr[++K]=z[Z],--Z);sr[++K]='
';
 23 }
 24 const int N=20005;
 25 int head[N],Next[N<<1],ver[N<<1],edge[N<<1],tot=1;
 26 inline void add(int u,int v,int e){
 27     ver[++tot]=v,Next[tot]=head[u],head[u]=tot,edge[tot]=e;
 28 }
 29 int dfn[N],top[N],sz[N],son[N],num[N],val[N],dep[N],fa[N],cnt,n,m;
 30 void dfs1(int u){
 31     sz[u]=1,dep[u]=dep[fa[u]]+1;
 32     for(int i=head[u];i;i=Next[i]){
 33         int v=ver[i];
 34         if(v!=fa[u]){
 35             fa[v]=u,num[i>>1]=v,dfs1(v),sz[u]+=sz[v];
 36             if(sz[son[u]]<sz[v]) son[u]=v;
 37         }
 38     }
 39 }
 40 void dfs2(int u,int t){
 41     top[u]=t,dfn[u]=++cnt;
 42     if(son[u]){
 43         dfs2(son[u],t);
 44         for(int i=head[u];i;i=Next[i])
 45         if(ver[i]!=fa[u]&&ver[i]!=son[u])
 46         dfs2(ver[i],ver[i]);
 47     }
 48 }
 49 int mx[N<<2],mn[N<<2],sum[N<<2],rev[N<<2];
 50 #define ls (p<<1)
 51 #define rs (p<<1|1)
 52 inline void upd(int p){
 53     mx[p]=max(mx[ls],mx[rs]),mn[p]=min(mn[ls],mn[rs]),sum[p]=sum[ls]+sum[rs];
 54 }
 55 inline void ppd(int p){
 56     rev[p]^=1,sum[p]=-sum[p],swap(mn[p],mx[p]),mn[p]=-mn[p],mx[p]=-mx[p];
 57 }
 58 inline void pd(int p){
 59     if(rev[p]){
 60         ppd(ls),ppd(rs);
 61         rev[p]=0;
 62     }
 63 }
 64 void build(int p,int l,int r){
 65     if(l==r) return (void)(mx[p]=mn[p]=sum[p]=val[l]);
 66     int mid=(l+r)>>1;
 67     build(ls,l,mid),build(rs,mid+1,r);
 68     upd(p);
 69 }
 70 void update(int p,int l,int r,int x){
 71     if(l==r) return (void)(mn[p]=mx[p]=sum[p]=val[l]);
 72     int mid=(l+r)>>1;pd(p);
 73     x<=mid?update(ls,l,mid,x):update(rs,mid+1,r,x);
 74     upd(p);
 75 }
 76 void Rev(int p,int l,int r,int ql,int qr){
 77     if(ql<=l&&qr>=r) return (void)(ppd(p));
 78     int mid=(l+r)>>1;pd(p);
 79     if(ql<=mid) Rev(ls,l,mid,ql,qr);
 80     if(qr>mid) Rev(rs,mid+1,r,ql,qr);
 81     upd(p);
 82 }
 83 int querysum(int p,int l,int r,int ql,int qr){
 84     if(ql<=l&&qr>=r) return sum[p];
 85     int mid=(l+r)>>1,res=0;pd(p);
 86     if(ql<=mid) res+=querysum(ls,l,mid,ql,qr);
 87     if(qr>mid) res+=querysum(rs,mid+1,r,ql,qr);
 88     return res;
 89 }
 90 int querymax(int p,int l,int r,int ql,int qr){
 91     if(ql<=l&&qr>=r) return mx[p];
 92     int mid=(l+r)>>1,res=-inf;pd(p);
 93     if(ql<=mid) cmax(res,querymax(ls,l,mid,ql,qr));
 94     if(qr>mid) cmax(res,querymax(rs,mid+1,r,ql,qr));
 95     return res;
 96 }
 97 int querymin(int p,int l,int r,int ql,int qr){
 98     if(ql<=l&&qr>=r) return mn[p];
 99     int mid=(l+r)>>1,res=inf;pd(p);
100     if(ql<=mid) cmin(res,querymin(ls,l,mid,ql,qr));
101     if(qr>mid) cmin(res,querymin(rs,mid+1,r,ql,qr));
102     return res;
103 }
104 void change(int i,int x){
105     val[dfn[num[i]]]=x,update(1,1,n,dfn[num[i]]);
106 }
107 void RRR(int u,int v){
108     while(top[u]!=top[v]){
109         if(dep[top[u]]<dep[top[v]]) swap(u,v);
110         Rev(1,1,n,dfn[top[u]],dfn[u]);u=fa[top[u]];
111     }
112     if(u!=v){
113         if(dep[u]<dep[v]) swap(u,v);
114         Rev(1,1,n,dfn[son[v]],dfn[u]);
115     }
116 }
117 int SUM(int u,int v){
118     int res=0;
119     while(top[u]!=top[v]){
120         if(dep[top[u]]<dep[top[v]]) swap(u,v);
121         res+=querysum(1,1,n,dfn[top[u]],dfn[u]);u=fa[top[u]];
122     }
123     if(u!=v){
124         if(dep[u]<dep[v]) swap(u,v);
125         res+=querysum(1,1,n,dfn[son[v]],dfn[u]);
126     }
127     return res;
128 }
129 int MAX(int u,int v){
130     int res=-inf;
131     while(top[u]!=top[v]){
132         if(dep[top[u]]<dep[top[v]]) swap(u,v);
133         cmax(res,querymax(1,1,n,dfn[top[u]],dfn[u]));u=fa[top[u]];
134     }
135     if(u!=v){
136         if(dep[u]<dep[v]) swap(u,v);
137         cmax(res,querymax(1,1,n,dfn[son[v]],dfn[u]));
138     }
139     return res;
140 }
141 int MIN(int u,int v){
142     int res=inf;
143     while(top[u]!=top[v]){
144         if(dep[top[u]]<dep[top[v]]) swap(u,v);
145         cmin(res,querymin(1,1,n,dfn[top[u]],dfn[u]));u=fa[top[u]];
146     }
147     if(u!=v){
148         if(dep[u]<dep[v]) swap(u,v);
149         cmin(res,querymin(1,1,n,dfn[son[v]],dfn[u]));
150     }
151     return res;
152 }
153 char s[15];
154 int main(){
155 //    freopen("testdata.in","r",stdin);
156     n=read();
157     for(int i=1,u,v,e;i<n;++i)
158     u=read()+1,v=read()+1,e=read(),add(u,v,e),add(v,u,e);
159     dfs1(1),dfs2(1,1);
160     for(int i=1;i<n;++i) val[dfn[num[i]]]=edge[i<<1];
161     build(1,1,n);
162     m=read();
163     while(m--){
164         scanf("%s",s+1);int u=read()+1,v=read()+1;
165         switch(s[1]){
166             case 'C':--u,--v,change(u,v);break;
167             case 'N':RRR(u,v);break;
168             case 'S':print(SUM(u,v));break;
169             default:{
170                 print(s[2]=='A'?MAX(u,v):MIN(u,v));
171                 break;
172             }
173         }
174     }
175     Ot();
176     return 0;
177 }
原文地址:https://www.cnblogs.com/bztMinamoto/p/9799433.html