bzoj 2157 旅行

题目大意:

一个树 支持以下五种操作

C i w,表示对于经过第i条边的权值变成了w

N u v,表示u 到v 的路径上的所有边的权值都变成原来的相反数。

SUM u v,表示询问从u 到v 所获得的边权和

MAX u v,表示询问从u 到v 的路径上的边权最大值

MIN u v,表示询问从u 到v 的路径上的边权最小值

思路:

树链剖分

把每条边的权值都记在深度靠下的点里

然后对于线段树打一个tag记录是否要进行N操作

对于这个tag每次update时要XOR!!!

因为有可能连续N两次

然后就正常操作了

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<vector>
  8 #include<queue>
  9 #define inf 2139062143
 10 #define ll long long
 11 #define MAXN 20101  
 12 using namespace std;
 13 inline int read()
 14 {
 15     int x=0,f=1;char ch=getchar();
 16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
 17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
 18     return x*f;
 19 }
 20 int nxt[MAXN<<1],fst[MAXN],n,to[MAXN<<1],Val[MAXN<<1],Cnt,val[MAXN];
 21 int cnt[MAXN],bl[MAXN],fa[MAXN],dep[MAXN],hsh[MAXN];
 22 struct data {int l,r,mn,mx,sum;bool tag;}tr[MAXN<<2];
 23 void add(int u,int v,int w) {nxt[++Cnt]=fst[u],fst[u]=Cnt,to[Cnt]=v,Val[Cnt]=w;}
 24 void dfs(int x)
 25 {
 26     cnt[x]=1;
 27     for(int i=fst[x];i;i=nxt[i])
 28     {
 29         if(to[i]==fa[x]) continue;
 30         val[to[i]]=Val[i],fa[to[i]]=x,dep[to[i]]=dep[x]+1;
 31         dfs(to[i]);
 32         cnt[x]+=cnt[to[i]];
 33     }
 34 }
 35 void Dfs(int x,int anc)
 36 {
 37     int hvs=0;hsh[x]=++Cnt,bl[x]=anc;
 38     for(int i=fst[x];i;i=nxt[i])
 39         if(to[i]!=fa[x]&&cnt[to[i]]>cnt[hvs]) hvs=to[i];
 40     if(!hvs) return ;
 41     Dfs(hvs,anc);
 42     for(int i=fst[x];i;i=nxt[i])
 43         if(to[i]!=fa[x]&&to[i]!=hvs) Dfs(to[i],to[i]);
 44 }
 45 void build(int k,int l,int r)
 46 {
 47     tr[k].l=l,tr[k].r=r,tr[k].tag=0;
 48     if(l==r) return ;
 49     int mid=(l+r)>>1;
 50     build(k<<1,l,mid);
 51     build(k<<1|1,mid+1,r);
 52 }
 53 void pushdown(int k)
 54 {
 55     tr[k<<1].tag^=1,tr[k<<1|1].tag^=1;
 56     swap(tr[k<<1].mx,tr[k<<1].mn);swap(tr[k<<1|1].mx,tr[k<<1|1].mn);
 57     tr[k<<1].mx=-tr[k<<1].mx,tr[k<<1].mn=-tr[k<<1].mn,tr[k<<1].sum=-tr[k<<1].sum;
 58     tr[k<<1|1].mx=-tr[k<<1|1].mx,tr[k<<1|1].mn=-tr[k<<1|1].mn,tr[k<<1|1].sum=-tr[k<<1|1].sum;
 59     tr[k].tag=0;
 60 }
 61 void upd(int k,int pos,int x)
 62 {
 63     int l=tr[k].l,r=tr[k].r;
 64     if(l==r) {tr[k].sum=tr[k].mn=tr[k].mx=x;return ;}
 65     if(tr[k].tag) pushdown(k);
 66     int mid=(l+r)>>1;
 67     if(mid>=pos) upd(k<<1,pos,x);
 68     else upd(k<<1|1,pos,x);
 69     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
 70     tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
 71     tr[k].mn=min(tr[k<<1].mn,tr[k<<1|1].mn);
 72 }
 73 void Upd(int k,int a,int b)
 74 {
 75     if(a>b) return ;
 76     int l=tr[k].l,r=tr[k].r;
 77     if(l==a&&r==b) 
 78     {
 79         tr[k].sum=-tr[k].sum;
 80         swap(tr[k].mx,tr[k].mn);
 81         tr[k].mx=-tr[k].mx,tr[k].mn=-tr[k].mn,tr[k].tag^=1;return ;
 82     }
 83     if(tr[k].tag) pushdown(k);
 84     int mid=(l+r)>>1;
 85     if(mid>=b) Upd(k<<1,a,b);
 86     else if(mid<a) Upd(k<<1|1,a,b);
 87     else {Upd(k<<1,a,mid);Upd(k<<1|1,mid+1,b);}
 88     tr[k].sum=tr[k<<1].sum+tr[k<<1|1].sum;
 89     tr[k].mx=max(tr[k<<1].mx,tr[k<<1|1].mx);
 90     tr[k].mn=min(tr[k<<1].mn,tr[k<<1|1].mn);
 91 }
 92 int query(int k,int a,int b,int x)
 93 {
 94     if(a>b&&x>0) return -inf;
 95     if(a>b&&x<0) return inf;
 96     if(a>b&&x==0) return 0;
 97     int l=tr[k].l,r=tr[k].r;
 98     if(a==l&&b==r)
 99     {
100         if(x>0) return tr[k].mx;
101         if(x<0) return tr[k].mn;
102         if(x==0) return tr[k].sum;
103     }
104     if(tr[k].tag) pushdown(k);
105     int mid=(l+r)>>1;
106     if(mid>=b) return query(k<<1,a,b,x);
107     else if(mid<a) return query(k<<1|1,a,b,x);
108     else
109     {
110         if(x>0) return max(query(k<<1,a,mid,x),query(k<<1|1,mid+1,b,x));
111         if(x<0) return min(query(k<<1,a,mid,x),query(k<<1|1,mid+1,b,x));
112         if(x==0) return query(k<<1,a,mid,x)+query(k<<1|1,mid+1,b,x);
113     }
114 }
115 int main()
116 {
117     n=read();int a,b,c;
118     for(int i=1;i<n;i++) {a=read()+1,b=read()+1,c=read();add(a,b,c);add(b,a,c);}
119     dep[1]=1,fa[1]=1;
120     dfs(1);Cnt=0;
121     Dfs(1,1);
122     build(1,1,n);
123     for(int i=1;i<=n;i++) upd(1,hsh[i],val[i]);
124     int T=read(),t,res;char ch[7];
125     while(T--)
126     {
127         scanf("%s",ch);a=read()+1,b=read()+1;
128         if(ch[0]=='C')
129         {
130             a--;
131             t=a<<1;
132             if(fa[to[t]]==to[t-1]) c=to[t];
133             else c=to[t-1];
134             upd(1,hsh[c],b-1);
135         }
136         else if(ch[0]=='N')
137         {
138             while(bl[a]!=bl[b])
139             {
140                 if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
141                 Upd(1,hsh[bl[a]],hsh[a]);
142                 a=fa[bl[a]];
143             }
144             Upd(1,min(hsh[a],hsh[b])+1,max(hsh[a],hsh[b]));
145         }
146         else
147         {
148             if(ch[0]=='S') t=0;
149             else if(ch[1]=='A') t=1;
150             else if(ch[1]=='I') t=-1;
151             if(t<0) res=inf;
152             if(t>0) res=-inf;
153             if(t==0)res=0;
154             while(bl[a]!=bl[b])
155             {
156                 if(dep[bl[a]]<dep[bl[b]]) swap(a,b);
157                 if(t==0) res+=query(1,hsh[bl[a]],hsh[a],t);
158                 if(t<0) res=min(res,query(1,hsh[bl[a]],hsh[a],t));
159                 if(t>0) res=max(res,query(1,hsh[bl[a]],hsh[a],t));
160                 a=fa[bl[a]];
161             }
162             if(t==0) res+=query(1,min(hsh[a],hsh[b])+1,max(hsh[a],hsh[b]),t);
163             if(t<0) res=min(res,query(1,min(hsh[a],hsh[b])+1,max(hsh[a],hsh[b]),t));
164             if(t>0) res=max(res,query(1,min(hsh[a],hsh[b])+1,max(hsh[a],hsh[b]),t));
165             printf("%d\n",res);
166         }
167     }
168 }
View Code

没看题解调这道题调了5h

posted @ 2017-12-05 17:39  jack_yyc  阅读(128)  评论(0编辑  收藏  举报