zoukankan      html  css  js  c++  java
  • BZOJ 2843 极地旅行社

    【题解】  

      这道题其实有个树状数组维护dfs序的做法,不过懒得想那么多直接写了Link-Cut Tree

      

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define N 600010
     4 #define rg register
     5 #define ls (c[u][0])
     6 #define rs (c[u][1])
     7 using namespace std;
     8 int n,m,x,y,top,val[N],c[N][2],fa[N],sum[N],st[N],rev[N];
     9 char opt[50];
    10 inline int read(){
    11     int k=0,f=1; char c=getchar();
    12     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    13     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    14     return k*f;
    15 }
    16 inline bool isroot(int u){
    17     return c[fa[u]][0]!=u&&c[fa[u]][1]!=u;
    18 }
    19 inline bool which(int u){
    20     return c[fa[u]][1]==u;
    21 }
    22 inline void pushup(int u){
    23     sum[u]=sum[ls]+sum[rs]+val[u];
    24 }
    25 inline void pushdown(int u){
    26     if(rev[u]) rev[ls]^=1,rev[rs]^=1,rev[u]=0,swap(ls,rs);
    27 }
    28 void rotate(int u){
    29     int f=fa[u],gf=fa[f],wh=which(u);
    30     if(!isroot(f)) c[gf][which(f)]=u;
    31     fa[u]=gf; fa[f]=u; fa[c[u][wh^1]]=f;
    32     c[f][wh]=c[u][wh^1]; c[u][wh^1]=f;
    33     pushup(f); pushup(u);
    34 }
    35 void splay(int u){
    36     st[top=1]=u;
    37     for(rg int i=u;!isroot(i);i=fa[i]) st[++top]=fa[i];
    38     for(rg int i=top;i;i--) pushdown(st[i]);
    39     while(!isroot(u)){
    40         if(!isroot(fa[u])) rotate(which(u)==which(fa[u])?fa[u]:u);
    41         rotate(u);
    42     }
    43 }
    44 void access(int u){
    45     for(rg int son=0;u;son=u,u=fa[u]) splay(u),c[u][1]=son,pushup(u);
    46 }
    47 void makeroot(int u){
    48     access(u); splay(u); rev[u]^=1;
    49 }
    50 int find(int u){
    51     access(u); splay(u);
    52     while(ls) u=ls; return u;
    53 }
    54 void split(int x,int y){
    55     makeroot(x); access(y); splay(y);
    56 }
    57 void cut(int x,int y){
    58     split(x,y);
    59     if(c[y][0]==x) c[y][0]=0,fa[x]=0;
    60 }
    61 void link(int x,int y){
    62     makeroot(x); fa[x]=y;
    63 }
    64 int main(){
    65     n=read();
    66     for(rg int i=1;i<=n;i++) val[i]=sum[i]=read();
    67     m=read();
    68     while(m--){
    69         scanf("%s",opt+1); x=read(); y=read();
    70         if(opt[1]=='b'){
    71             if(find(x)==find(y)) puts("no");
    72             else{
    73                 puts("yes");
    74                 link(x,y);
    75             }
    76         }
    77         if(opt[1]=='p'){
    78             access(x); splay(x); val[x]=y; pushup(x);
    79         }
    80         if(opt[1]=='e'){
    81             if(find(x)!=find(y)) puts("impossible");
    82             else{
    83                 split(x,y);
    84                 printf("%d
    ",sum[y]);
    85             }
    86         }
    87     }
    88     return 0;
    89 }
    View Code
  • 相关阅读:
    Python入门11 —— 基本数据类型的操作
    Win10安装7 —— 系统的优化
    Win10安装6 —— 系统的激活
    Win10安装5 —— 系统安装步骤
    Win10安装4 —— 通过BIOS进入PE
    Win10安装2 —— 版本的选择与下载
    Win10安装1 —— 引言与目录
    Win10安装3 —— U盘启动工具安装
    虚拟机 —— VMware Workstation15安装教程
    Python入门10 —— for循环
  • 原文地址:https://www.cnblogs.com/DriverLao/p/8744994.html
Copyright © 2011-2022 走看看