spoj6779 Can you answer these queries VII(gss7)动态树
2012-12-09 18:05
375 查看
看了一下题,二话没说,想拍一个树链剖分,像线段树维护一下4个值就行了,可是想想树链剖分那长长的代码,额~(⊙o⊙)…
突然想到一句话,一切尽动态树。
先把建立一颗树吧 ,这里用1作为根, 这样的话这棵树就已经定型了。 刚开始每个节点只记录双亲。 这样任意两个节点 向着根所走过的路 要吗在路中间有交点,要么在根上有交点,要么就直接交与这两个点的某一个点了。利用这个性质我们可以yy很多东西呀~~~
突然想到一句话,一切尽动态树。
先把建立一颗树吧 ,这里用1作为根, 这样的话这棵树就已经定型了。 刚开始每个节点只记录双亲。 这样任意两个节点 向着根所走过的路 要吗在路中间有交点,要么在根上有交点,要么就直接交与这两个点的某一个点了。利用这个性质我们可以yy很多东西呀~~~
#define fi freopen("in.txt","r",stdin) #include <stdio.h> #include <iostream> #include <string.h> #include <cmath> #include <vector> #include <algorithm> using namespace std; #define sfint(x) scanf("%d",&x) #define sfint2(x,y) scanf("%d%d",&x,&y) #define sfint3(x,y,z) scanf("%d%d%d",&x,&y,&z) #define sfstr(c) scanf("%s",c) #define pfint(x) printf("%d\n",x) #define fr(i,s,n) for(i=s;i<n;++i) #define _fr(i,n,s) for(i=n-1;i>=s;--i) #define cl(a) memset(a,0,sizeof(a)) const int NMax =100100; const int M = 200010; struct Edg { int u,v,nxt; }edg[M]; int tote,head[NMax]; int num; void init(){ tote = 0; memset(head,-1,sizeof(head)); } inline void addedg(int u,int v){ edg[tote].u=u;edg[tote].v=v;edg[tote].nxt=head[u];head[u]=tote++; }; struct node { int val,mx,lmx,rmx,sum,siz; bool chg; node *l,*r,*f; void Chg(int x){ chg = 1; val = x; sum = x*siz; mx = lmx = rmx = (x > 0) ? sum : 0; } void down(); void update() { siz = l->siz + r->siz +1; sum = l->sum + r->sum + val; mx = max(max(l->mx,r->mx),l->rmx+r->lmx+val); lmx = max(l->lmx,l->sum+val+r->lmx); rmx = max(r->rmx,r->sum+val+l->rmx); } } nodes[NMax],*nil=nodes; int n,m; void node::down(){ if (chg){ if (l!=nil) l->Chg(val); if (r!=nil) r->Chg(val); chg = 0; } } class Lct { public: void zig(node *p) { node *q=p->f,*y=q->f; q->down();p->down(); if ((q->l=p->r))q->l->f=q; p->r=q; q->f=p; p->f=y; if (y!=nil) { if (y->l==q)y->l=p; else if (y->r==q)y->r=p; } q->update(); } void zag(node *p) { node *q=p->f,*y=q->f; q->down(); p->down(); if ((q->r=p->l))q->r->f=q; p->l=q; q->f=p; p->f=y; if (y!=nil) { if (y->l==q)y->l=p; else if (y->r==q)y->r=p; } q->update(); } void Splay(node *p) { p->down(); while ((p->f)!=nil && (p->f->l==p || p->f->r==p)) { node *q=p->f,*y=q->f; if (y!=nil && y->l==q) { if (q->l==p)zig(q),zig(p); else zag(p),zig(p); } else if (y!=nil && y->r==q) { if (q->r==p)zag(q),zag(p); else zig(p),zag(p); } else { if (q->l==p)zig(p); else zag(p); } } p->update(); } node *Expose(node *p){ node *q; for (q=nil; p!=nil; p=p->f){ Splay(p); p->r=q; (q=p)->update(); } return q; } void change(int x,int y,int c){ node *p=nodes+x,*q=nodes+y; Expose(p); node * root; for(root = nil; q!=nil; q=q->f){ Splay(q); if (q->f==nil) { q->r->Chg(c);root->Chg(c);q->val = c; } q->r = root; root = q; root->update(); } } int Ask(int x,int y) { node *p=nodes+x,*q=nodes+y; Expose(p); node * root; for(root = nil; q!=nil; q=q->f){ Splay(q); if (q->f==nil) { int ans = max(q->r->mx,root->mx); ans = max(ans,q->r->lmx+root->lmx+q->val); return ans; }e q->r = root; root = q; root->update(); } } }lct; int q[NMax]; void bfs(){ int f=0,r=1,i,u,v; q[0] = 1; for (i=0;i<=n;i++)nodes[i].f=nil; while(f!=r){ u = q[f++]; for(i = head[u];i!=-1;i=edg[i].nxt){ v = edg[i].v; if (v!=1 && nodes[v].f == nil){ nodes[v].f=nodes+u; q[r++] = v; } } } } void make_map(){ int i,u,v; sfint(n); fr(i , 1,n+1){ sfint(num); nodes[i].siz =1; nodes[i].val = nodes[i].sum = nodes[i].mx = nodes[i].lmx = nodes[i].rmx = num; nodes[i].l = nodes[i].r = nil; } init(); fr(i,0,n-1){ sfint2(u,v); addedg(u,v); addedg(v,u); } bfs(); } void solve(){ int i,op,u,v,w; sfint(m); fr(i,0,m){ sfint(op); if (op ==1){ sfint2(u,v); pfint(lct.Ask(u,v)); } else{ sfint3(u,v,w); lct.change(u,v,w); } } } int main() { #ifdef loca fi; #endif nil->siz = 0;nil->l = nil->r = nil;nil->mx = nil->lmx=nil->rmx = nil->val = 0; make_map(); solve(); return 0; }
相关文章推荐
- GSS7 spoj 6779. Can you answer these queries VII 树链剖分+线段树
- SPOJ 6779 Can you answer these queries VII(动态树)
- GSS1 - Can you answer these queries I(动态查询区间最大连续和)
- SPOJ GSS7 Can you answer these queries VII ——树链剖分 线段树
- SPOJ-GSS7 Can you answer these queries VII(树上区间最大和)
- SPOJGSS7 Can you answer these queries VII
- SPOJ GSS7 Can you answer these queries VII(LCT)
- SPOJ GSS1 Can you answer these queries I
- SPOJ 1043 Can you answer these queries I(GSS1 线段树)
- SPOJ GSS3 Can you answer these queries III[线段树]
- SPOJ GSS3 Can you answer these queries III
- SPOJ GSS3 Can you answer these queries III
- SPOJ GSS1 Can you answer these queries I
- SPOJ GSS2 Can you answer these queries II
- spojGSS2 1557 Can you answer these queries II(成段更新)
- 【SPOJ】6779 Can you answer these queries VII 树链剖分+线段树 求树上的最大子段和
- SPOJ GSS1 Can you answer these queries I
- SPOJ GSS3 Can you answer these queries III
- GSS1 spoj 1043 Can you answer these queries I 最大子段和
- SPOJ GSS3 Can you answer these queries III