标签:
树链剖分边更新,线段树区间更新(取相反数)+单点更新,区间查询最大值,区间取相反数的操作可以维护两个值mmax和mmin,当取反时最大最小值取反互换
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 #define lson l,m,rt<<1 6 #define rson m+1,r,rt<<1|1 7 const int maxn = 100005; 8 const int INF = 0x3f3f3f3f; 9 int siz[maxn],son[maxn],dep[maxn],tid[maxn],top[maxn],fa[maxn]; 10 int head[maxn],cnt,lable; 11 int n,m; 12 struct edge 13 { 14 int v,next,w,en; 15 }e[maxn*2]; 16 int mmax[maxn<<2],mmin[maxn<<2],lazy[maxn<<2]; 17 void init() 18 { 19 memset(head,-1,sizeof(head)); 20 cnt = lable = 0; 21 } 22 void add(int u,int v,int w) 23 { 24 e[cnt].v = v; 25 e[cnt].w = w; 26 e[cnt].next = head[u]; 27 head[u] = cnt++; 28 } 29 void find_heavy(int rt,int father,int depth) 30 { 31 int maxsize = 0; 32 fa[rt] = father; 33 son[rt] = 0; 34 siz[rt] = 1; 35 dep[rt] = depth; 36 for(int i = head[rt];i!=-1;i = e[i].next)if(e[i].v!=father){ 37 e[i].en = e[i^1].en = e[i].v; 38 find_heavy(e[i].v,rt,depth+1); 39 siz[rt]+=siz[e[i].v]; 40 if(siz[e[i].v]>maxsize){ 41 son[rt] = e[i].v,maxsize = siz[e[i].v]; 42 } 43 } 44 } 45 void connect(int rt,int anc) 46 { 47 tid[rt] = ++lable; 48 top[rt] = anc; 49 if(son[rt])connect(son[rt],anc); 50 for(int i = head[rt];i!=-1;i=e[i].next) 51 if(e[i].v!=fa[rt]&&e[i].v!=son[rt]) 52 connect(e[i].v,e[i].v); 53 } 54 void pushup(int rt) 55 { 56 mmax[rt] = max(mmax[rt<<1],mmax[rt<<1|1]); 57 mmin[rt] = min(mmin[rt<<1],mmin[rt<<1|1]); 58 } 59 void pushdown(int rt) 60 { 61 if(lazy[rt]==-1) 62 { 63 int t = mmax[rt<<1]; 64 mmax[rt<<1] = -mmin[rt<<1]; 65 mmin[rt<<1] = -t; 66 t = mmax[rt<<1|1]; 67 mmax[rt<<1|1] = -mmin[rt<<1|1]; 68 mmin[rt<<1|1] = -t; 69 if(lazy[rt<<1]==0)lazy[rt<<1] = -1; 70 else lazy[rt<<1]*=-1; 71 if(lazy[rt<<1|1]==0)lazy[rt<<1|1] = -1; 72 else lazy[rt<<1|1]*=-1; 73 lazy[rt] = 0; 74 } 75 else lazy[rt] = 0; 76 } 77 int query(int L,int R,int l,int r,int rt) 78 { 79 if(L<=l&&r<=R)return mmax[rt]; 80 pushdown(rt); 81 int m = (l+r)>>1,ret = -INF; 82 if(L<=m)ret = max(ret,query(L,R,lson)); 83 if(m<R)ret = max(ret,query(L,R,rson)); 84 return ret; 85 } 86 int getmmax(int x,int y) 87 { 88 int ans = -INF; 89 while(top[x]!=top[y]) 90 { 91 if(dep[top[x]]<dep[top[y]])swap(x,y); 92 ans = max(ans,query(tid[top[x]],tid[x],1,n,1)); 93 x = fa[top[x]]; 94 } 95 if(dep[x]>dep[y])swap(x,y); 96 if(x==y)return ans; 97 ans = max(ans,query(tid[son[x]],tid[y],1,n,1)); 98 return ans; 99 } 100 void update(int pos,int val,int l,int r,int rt) 101 { 102 if(l==r){ 103 mmax[rt] = val; 104 mmin[rt] = val; 105 return; 106 } 107 pushdown(rt); 108 int m = (l+r)>>1; 109 if(pos<=m)update(pos,val,lson); 110 else update(pos,val,rson); 111 pushup(rt); 112 } 113 void UPDATE(int L,int R,int l,int r,int rt) 114 { 115 if(L<=l&&r<=R){ 116 int t = mmax[rt]; 117 mmax[rt] = -mmin[rt]; 118 mmin[rt] = -t; 119 if(lazy[rt]==0)lazy[rt] = -1; 120 else lazy[rt]*=-1; 121 return; 122 } 123 pushdown(rt); 124 int m = (l+r)>>1; 125 if(L<=m)UPDATE(L,R,lson); 126 if(m<R)UPDATE(L,R,rson); 127 pushup(rt); 128 } 129 void change(int x,int y) 130 { 131 while(top[x]!=top[y]) 132 { 133 if(dep[top[x]]<dep[top[y]])swap(x,y); 134 UPDATE(tid[top[x]],tid[x],1,n,1); 135 x = fa[top[x]]; 136 } 137 if(dep[x]>dep[y])swap(x,y); 138 if(x!=y)UPDATE(tid[son[x]],tid[y],1,n,1); 139 } 140 int main() 141 { 142 int T;scanf("%d",&T); 143 while(T--) 144 { 145 init(); 146 scanf("%d",&n); 147 for(int i = 1;i<n;++i){ 148 int u,v,w;scanf("%d%d%d",&u,&v,&w); 149 add(u,v,w);add(v,u,w); 150 } 151 find_heavy(1,1,1); 152 connect(1,1); 153 for(int i = 0;i<cnt;i+=2)update(tid[e[i].en],e[i].w,1,n,1); 154 while(1) 155 { 156 char s[10];int a,b; 157 scanf("%s",s); 158 if(s[0]==‘D‘)break; 159 scanf("%d%d",&a,&b); 160 if(s[0]==‘Q‘)printf("%d\n",getmmax(a,b)); 161 else if(s[0]==‘C‘)update(tid[e[2*a-1].en],b,1,n,1); 162 else change(a,b); 163 } 164 } 165 return 0; 166 }
标签:
原文地址:http://www.cnblogs.com/GJKACAC/p/4683287.html