山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

bzoj 2843 极地旅行社(LCT)

 

【题目链接】

 

    http://www.lydsy.com/JudgeOnline/problem.php?id=2843

 

【题意】

 

    给定一个森林,要求提供连边,修改点值,查询路径和的操作。

 

【思路】

       

    LCT维护sum

   对于一棵树LCT用splay维护该树的若干重路径,u->fa有三种:一种满足(u->fa->ch[0]==u||u->fa->ch[1]==u),即splay辅助树中的父亲;一种不满足上述要求,即辅助树(不同重路径)之间的连接;另一种u->fa==null,为原树的根。

    查询两个节点是否连通即是否处于一棵原树,直接找到原树的根即可。

 

【代码】

 

 

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<iostream>
  4 #define FOR(a,b,c) for(int a=b;a<=c;a++)
  5 #define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
  6 using namespace std;
  7 
  8 typedef long long ll;
  9 typedef unsigned int ul;
 10 const int N = 4e5+10;
 11 
 12 ll read() {
 13     char c=getchar();
 14     ll f=1,x=0;
 15     while(!isdigit(c)) {
 16         if(c=='-') f=-1; c=getchar();
 17     }
 18     while(isdigit(c))
 19         x=x*10+c-'0',c=getchar();
 20     return x*f;
 21 }
 22 
 23 namespace LCT {
 24 
 25     struct Node {
 26         Node *ch[2],*fa;
 27         int rev,v,sum;
 28         Node() ;
 29         void reverse() {
 30             rev^=1;
 31             swap(ch[0],ch[1]);
 32         }
 33         void up_push() {
 34             if(fa->ch[0]==this||fa->ch[1]==this) 
 35                 fa->up_push();
 36             if(rev) {
 37                 ch[0]->reverse();
 38                 ch[1]->reverse();
 39                 rev=0;
 40             }
 41         }
 42         void maintain() {
 43             sum=ch[0]->sum+ch[1]->sum+v;
 44         }
 45     } *null=new Node,T[N];
 46     Node::Node() {
 47         v=sum=rev=0;
 48         fa=ch[0]=ch[1]=null;
 49     }
 50     
 51     void rot(Node* o,int d) {
 52         Node *p=o->fa;
 53         p->ch[d]=o->ch[d^1];
 54         o->ch[d^1]->fa=p;
 55         o->ch[d^1]=p;
 56         o->fa=p->fa;
 57         if(p==p->fa->ch[0])
 58             p->fa->ch[0]=o;
 59         else if(p==p->fa->ch[1])
 60             p->fa->ch[1]=o;
 61         p->fa=o;
 62         p->maintain();
 63     }
 64     void splay(Node *o) {
 65         o->up_push();
 66         Node *nf,*nff;
 67         while(o->fa->ch[0]==o||o->fa->ch[1]==o) {
 68             nf=o->fa,nff=nf->fa;
 69             if(o==nf->ch[0]) {
 70                 if(nf==nff->ch[0]) rot(nf,0);
 71                 rot(o,0);
 72             } else {
 73                 if(nf==nf->ch[1]) rot(nf,1);
 74                 rot(o,1);
 75             }
 76         }
 77         o->maintain();
 78     }
 79     void Access(Node* o) {
 80         Node *son=null;
 81         while(o!=null) {
 82             splay(o);
 83             o->ch[1]=son;
 84             o->maintain();
 85             son=o; o=o->fa;
 86         }
 87     }
 88     void evert(Node* o) {
 89         Access(o);
 90         splay(o);
 91         o->reverse();
 92     }
 93     void Link(Node* u,Node* v) {
 94         evert(u);
 95         u->fa=v;
 96     }
 97     void Cut(Node* u,Node* v) {
 98         evert(u);
 99         Access(v); splay(v);
100         u->fa=v->ch[0]=null;
101         v->maintain();
102     }
103     Node* find(Node* o) {
104         while(o->fa!=null) o=o->fa;
105         return o;
106     }
107 }
108 using namespace LCT;
109 
110 int n,q;
111 
112 int main()
113 {
114     n=read();
115     FOR(i,1,n) {
116         int x=read();
117         T[i].sum=T[i].v=x;
118     }
119     q=read();
120     char op[20];
121     int u,v;
122     while(q--) {
123         scanf("%s",&op);
124         u=read(),v=read();
125         if(op[0]=='b') {
126             if(find(&T[u])==find(&T[v])) puts("no");
127             else {
128                 puts("yes");
129                 Link(&T[u],&T[v]);
130             }
131         } else 
132         if(op[0]=='p') {
133             evert(&T[u]);
134             T[u].v=v;
135             T[u].maintain();
136         } else {
137             if(find(&T[u])!=find(&T[v])) puts("impossible");
138             else {
139                 evert(&T[u]);
140                 Access(&T[v]); splay(&T[v]);
141                 printf("%d\n",T[v].sum);
142             }
143         }
144     }
145     return 0;
146 }

 

posted on 2016-03-25 18:24  hahalidaxin  阅读(277)  评论(0编辑  收藏  举报