spoj6779 Can you answer these queries VII(gss7)动态树

来源:互联网 发布:ps做淘宝详情页切片 编辑:程序博客网 时间:2024/06/12 00:24

 看了一下题,二话没说,想拍一个树链剖分,像线段树维护一下4个值就行了,可是想想树链剖分那长长的代码,额~(⊙o⊙)…  

突然想到一句话,一切尽动态树。  

先把建立一颗树吧 ,这里用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;}eq->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 locafi;#endifnil->siz = 0;nil->l = nil->r = nil;nil->mx = nil->lmx=nil->rmx = nil->val = 0;make_map();solve();return 0;}


原创粉丝点击