zoukankan      html  css  js  c++  java
  • 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
    ",T[v].sum);
    142             }
    143         }
    144     }
    145     return 0;
    146 }
  • 相关阅读:
    django 项目运行时static静态文件不能加载问题处理
    django 项目运行时media静态文件不能加载问题处理
    django 的用户验证及登录状态保持
    django 2.0 中URL的include方法使用分析
    auth.User.groups: (fields.E304)
    web理论知识--HTML结构及标签
    数据库相关--mysql中的单表查询
    python基础下的数据结构与算法之链表
    python基础下的数据结构与算法之顺序表
    Nginx 日志分析命令
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5320564.html
Copyright © 2011-2022 走看看