标签:des blog http io os ar java for strong
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 442 Accepted Submission(s): 122
思路:lct or 树链分割
调了三天,终于过了,。。。不容易呀。。。
#pragma comment(linker, "/STACK:102400000,102400000") #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<set> #include<stack> #include<map> #include<ctime> #include<bitset> #define LL long long #define INF 999999 #define mod 20140518 #define maxn 50010 using namespace std; int head[maxn],next1[maxn*2],to[maxn*2] ; int top1 ; bool vi[maxn] ; struct node { int Max,Min; int add,lans,rans; }tree[maxn*3],num[maxn]; int ql,qr,val ; node vv ; int max(int x,int y ){return x > y?x:y;} int min(int x,int y ){return x < y?x:y;} void Unit(int u,int v ) { next1[top1] = head[u] ;to[top1] = v ; head[u] = top1++; } void up(int o ) { tree[o].Max = max(tree[o<<1].Max,tree[o<<1|1].Max) ; tree[o].Min = min(tree[o<<1].Min,tree[o<<1|1].Min) ; tree[o].lans = max(tree[o<<1].lans,tree[o<<1|1].lans) ; tree[o].lans = max(tree[o].lans,tree[o<<1].Max-tree[o<<1|1].Min) ; tree[o].rans = max(tree[o<<1].rans,tree[o<<1|1].rans) ; tree[o].rans = max(tree[o].rans,tree[o<<1|1].Max-tree[o<<1].Min) ; } void Add(int o ,int add) { tree[o].add += add ; tree[o].Max += add ; tree[o].Min += add ; } void down(int o ) { if(tree[o].add) { Add((o<<1),tree[o].add) ; Add((o<<1|1),tree[o].add) ; tree[o].add = 0; } } void insert(int L,int R,int o ) { tree[o].add=0; if(L==R) { tree[o] = num[L] ; return ; } int mid=(L+R)>>1 ; insert(L,mid,o<<1) ; insert(mid+1,R,o<<1|1) ; up(o) ; } void update(int L,int R,int o ) { if(ql <= L && qr >= R) { Add(o,val) ; return ; } down(o) ; int mid=(L+R)>>1 ; if(ql <= mid)update(L,mid,o<<1) ; if(qr > mid) update(mid+1,R,o<<1|1) ; up(o); } void find(int L,int R,int o,node &c ) { if(ql <= L && qr >= R) { c = tree[o] ; return ; } int mid=(L+R)>>1 ; down(o) ; if(ql > mid) { find(mid+1,R,o<<1|1,c) ; return ; } else if(qr <= mid) { find(L,mid,o<<1,c) ; return ; } node a ; find(L,mid,o<<1,a) ; node b ; find(mid+1,R,o<<1|1,b) ; c.Max = max(a.Max,b.Max) ; c.Min = min(a.Min,b.Min) ; c.lans = max(a.lans,max(a.Max-b.Min,b.lans)) ; c.rans = max(a.rans,max(b.Max-a.Min,b.rans)) ; } int w[maxn],fa[maxn],top[maxn],sz ; int size1[maxn],son[maxn] ,dep[maxn]; void init() { memset(w,0,sizeof(w)); memset(size1,0,sizeof(size1)) ; memset(dep,0,sizeof(dep)) ; memset(son,0,sizeof(son)) ; memset(top,0,sizeof(top)) ; memset(fa,0,sizeof(fa)) ; } void dfs(int u) { size1[u] = 1 ;son[u] = 0 ; for(int i = head[u] ; i != -1 ; i = next1[i]) { int v = to[i] ; if(v==fa[u]) continue ; fa[v]=u; dep[v] = dep[u]+1; dfs(v) ; if(size1[v] > size1[son[u]]) son[u] = v ; size1[u] += size1[v] ; } } void build(int u,int t) { top[u] = t ; w[u] = ++sz ; if(son[u]) build(son[u],t) ; for(int i = head[u] ; i != -1 ; i = next1[i]) { int v = to[i] ; if(v==fa[u]||v==son[u]) continue ; build(v,v) ; } } int query(int u,int v ) { int f1,f2,flag=0,ans=0; node a[2],b,c,d; f1 = top[u] ; f2 = top[v] ; a[0].Max=a[1].Max=-1; while(f1 != f2) { // puts("=========="); if(dep[f1] < dep[f2]) { swap(f1,f2) ; swap(u,v) ; flag ^= 1; } ql = w[f1] ;qr = w[u] ; u = fa[f1] ;f1=top[u] ; find(1,sz,1,d) ; if(a[flag].Max==-1) { a[flag] = d ; continue ; } b = d ; d = a[flag] ; c.Max = max(d.Max,b.Max) ; c.Min = min(d.Min,b.Min) ; c.lans = max(d.lans,max(b.Max-d.Min,b.lans)) ; c.rans = max(d.rans,max(d.Max-b.Min,b.rans)) ; if(flag) ans = max(ans,c.rans) ; else ans = max(ans,c.lans); a[flag] = c ; } if(dep[u] < dep[v]) { swap(u,v) ; flag ^= 1; } ql = w[v] ; qr = w[u] ; find(1,sz,1,d) ; if(a[flag].Max!=-1){ b = d ; d = a[flag] ; c.Max = max(d.Max,b.Max) ; c.Min = min(d.Min,b.Min) ; c.lans = max(d.lans,max(b.Max-d.Min,b.lans)) ; c.rans = max(d.rans,max(d.Max-b.Min,b.rans)) ; if(flag) ans = max(ans,c.rans) ; else ans = max(ans,c.lans); a[flag] = c ; } else a[flag] = d ; if(a[0].Max==-1) { return max(ans,a[1].rans) ; } else if(a[1].Max==-1) { // puts("-----------"); // // cout << a[0].lans << "==" << a[0].rans << endl; return max(ans,a[0].lans) ; } ans = max(ans,a[1].rans); ans = max(ans,a[0].lans); ans = max(ans,a[1].Max-a[0].Min); return ans; } void ADD(int u,int v ,int c ) { int f1,f2; f1 = top[u];f2=top[v] ; val = c ; while(f1 != f2) { if(dep[f1] < dep[f2]) { swap(f1,f2) ; swap(u,v) ; } ql=w[f1] ;qr=w[u] ; u = fa[f1] ; f1 = top[u] ; update(1,sz,1) ; } if(dep[u] >dep[v]) swap(u,v) ; ql = w[u];qr=w[v] ; update(1,sz,1); } int next_int() { char c; int re = 0; c = getchar(); while (c < ‘0‘ || c > ‘9‘) c = getchar(); while (c >= ‘0‘ && c <= ‘9‘) { re = re*10+c-‘0‘; c = getchar(); } return re; } int ee[maxn] ; int main() { int n,m,x,y,i,j; int T,c ; //freopen("in.txt","r",stdin); scanf("%d",&T); while( T-- ) { n = next_int(); memset(head,-1,sizeof(head)) ; top1=0; for( i = 1 ; i <= n ;i++) { // scanf("%d",&ee[i]) ; ee[i]=next_int(); } for( i = 1 ; i < n ;i++) { // scanf("%d%d",&x,&y) ; x = next_int(); y = next_int(); Unit(x,y) ; Unit(y,x) ; } sz=0; init(); dfs(1) ; build(1,1); for( i = 1 ; i <= n ;i++) { ql=w[i]; vv.Max = ee[i]; vv.Min = ee[i] ; vv.lans = vv.rans = 0; num[ql] = vv ; } insert(1,sz,1); m = next_int(); while(m--) { // scanf("%d%d%d",&x,&y,&c) ; x = next_int(); y = next_int(); c = next_int(); printf("%d\n",query(x,y)) ; ADD(x,y,c) ; } } return 0 ; }
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<set> #include<stack> #include<map> #include<ctime> #include<bitset> #define LL long long #define INF 999999 #define mod 20140518 #define maxn 100010 using namespace std; int head[maxn],next1[maxn*2],to[maxn*2] ; int top ,n ; bool vi[maxn] ; void Unit(int u,int v ) { next1[top] = head[u] ;to[top] = v ; head[u] = top++; } struct LCT { int w[maxn],add[maxn],Max[maxn]; int ch[maxn][2],pre[maxn] ; int L[maxn] ; int Min[maxn],ans[maxn] ; bool rev[maxn] ; void init() { memset(rev,0,sizeof(rev)) ; memset(ch,0,sizeof(ch)) ; memset(add,0,sizeof(add)); memset(pre,0,sizeof(pre)) ; memset(Max,0,sizeof(Max)) ; memset(ans,0,sizeof(ans)) ; memset(Min,0,sizeof(Min)) ; memset(L,0,sizeof(L)) ; } void Add(int x ,int val) { if(x) { add[x] += val ; w[x] += val ; Max[x] += val ; Min[x] += val ; } } void update(int x ) { Max[x] = max(w[x],max(Max[ch[x][0]],Max[ch[x][1]])) ; Min[x] = w[x]; if(ch[x][1]) Min[x] = min(Min[ch[x][1]],Min[x]) ; if(ch[x][0]) Min[x] = min(Min[ch[x][0]],Min[x]) ; ans[x] = max(ans[ch[x][0]],max(0,ans[ch[x][1]])) ; if(ch[x][0]&&ch[x][1])ans[x] = max(ans[x],Max[ch[x][0]]-Min[ch[x][1]]) ; if(ch[x][0])ans[x] = max(ans[x],Max[ch[x][0]]-w[x]) ; if(ch[x][1])ans[x] = max(ans[x],w[x]-Min[ch[x][1]]) ; L[x] = max(L[ch[x][0]],max(0,L[ch[x][1]])) ; if(ch[x][0]&&ch[x][1])L[x] = max(L[x],Max[ch[x][1]]-Min[ch[x][0]]) ; if(ch[x][1])L[x] = max(L[x],Max[ch[x][1]]-w[x]) ; if(ch[x][0])L[x] = max(L[x],w[x]-Min[ch[x][0]]) ; } void down(int x ) { if(add[x]) { Add(ch[x][0],add[x]) ; Add(ch[x][1],add[x]) ; add[x]=0; } return ; if(rev[x]) { swap(ch[x][0],ch[x][1]) ; rev[ch[x][0]] ^= 1; rev[ch[x][1]] ^= 1; rev[x] = 0; } } bool isroot(int x ) { if(ch[pre[x]][0] != x && ch[pre[x]][1] != x ) return true ; return false; } void pushdown(int x ) { if(!isroot(x)) pushdown(pre[x]) ; down(x) ; } void rotate(int x,int f) { int y = pre[x],z = pre[y]; ch[y][!f] = ch[x][f]; pre[ ch[x][f] ] = y; pre[x] = pre[y]; if(ch[z][0] == y)ch[z][0] = x; else if(ch[z][1] == y)ch[z][1] = x; pre[y] = x; ch[x][f] = y; update(y); } void splay(int x) { pushdown(x); while(!isroot(x)) { if(isroot(pre[x]))rotate(x,ch[pre[x]][0] == x); else { int y = pre[x],z = pre[y]; int f = (ch[z][0] == y); if(ch[y][f] == x)rotate(x,!f),rotate(x,f); else rotate(y,f),rotate(x,f); } } update(x); } void access(int u) { for(int f = 0 ; u ;u = pre[u]) { splay(u); ch[u][1] = f ; update(u); f = u ; } } bool check(int a ,int b) { int x =a,y=b; access(y) ; for(int f = 0 ;x ;x = pre[x]) { splay(x) ; if(!pre[x]) break ; f = x ; } for( ; ch[x][1] ; x = ch[x][1]); return x == b ; } void make_root(int x ) { access(x) ; splay(x) ; rev[x] ^= 1; } void cut(int x,int y ) { if(x==y||!check(x,y)) { puts("-1") ; return ; } make_root(x) ; splay(y) ; pre[ch[y][0]] = pre[y] ; pre[y] = ch[y][0] = 0 ; } int find(int x,int y ) { access(y) ; for( int f = 0 ; x ; x = pre[x]) { splay(x) ; if(!pre[x]) { int Max1 = 0 ; Max1 = max(ans[f],L[ch[x][1]]); if(ch[x][1])Max1 = max(Max1,Max[ch[x][1]]-w[x]) ; if(f)Max1 = max(Max1,w[x]-Min[f]) ; if(ch[x][1]&&f) Max1= max(Max1,Max[ch[x][1]]-Min[f]); return Max1; } ch[x][1] = f ; f = x ; update(x) ; } return -1; } void add1(int x ,int y ,int add) { access(y) ; for(int f = 0 ; x ; x = pre[x]) { splay(x) ; if(!pre[x]) { w[x] += add ; Max[x] += add ; Min[x] += add ; Add(f,add) ; Add(ch[x][1],add) ; return ; } ch[x][1] = f ; f = x ; update(x) ; } } void link(int x,int y ) { make_root(x) ; pre[x]=y; } }lct; void dfs(int u,int f) { for(int i = head[u]; i != -1; i=next1[i]) { int v = to[i] ; if(v==f) continue ; dfs(v,u); lct.pre[v] = u; } } int next_int() { char ch; int res; bool neg; while (ch = getchar(), !isdigit(ch) && ch != ‘-‘) ; if (ch == ‘-‘) { neg = true; res = 0; } else { neg = false; res = ch - ‘0‘; } while (ch = getchar(), isdigit(ch)) res = res * 10 + ch - ‘0‘; return neg ? -res : res; } int main() { int n,m,i,j,k; int T,case1=0,u,v,c ; // freopen("in.txt","r",stdin); cin >> T ; while(T--) { scanf("%d",&n) ; lct.init(); for( i = 1 ; i <= n ;i++) { lct.w[i] = next_int() ; // lct.Max[i] = lct.Min[i] = lct.w[i]; } top=0; memset(head,-1,sizeof(head)) ; for( i = 1 ; i < n ;i++) { u = next_int(); v = next_int(); Unit(u,v) ; Unit(v,u) ; } dfs(1,-1); scanf("%d",&m) ; while(m--) { //scanf("%d%d%d",&u,&v,&c) ; u = next_int(); v = next_int(); c = next_int(); printf("%d\n",lct.find(u,v)) ; lct.add1(u,v,c) ; } } return 0 ; }
hdu 5052 Yaoge’s maximum profit
标签:des blog http io os ar java for strong
原文地址:http://www.cnblogs.com/20120125llcai/p/4005688.html