题目大意:
一个树 支持以下五种操作
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 ",res); 166 } 167 } 168 }
没看题解调这道题调了5h