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

    bzoj2843极地旅行社

    题意:

    一些点,每个点有一个权值。有三种操作:点与点连边,单点修改权值,求两点之间路径上点的权值和(需要判输入是否合法)

    题解:

    以前一直想不通为什么神犇们的模板中LCT在link和cut后都要在根节点打翻转标记。现在明白了,因为只有这样才能保持深度的正确性,以前没有因此炸过是因为我以前都是把LCT拿来当链剖用的,根本不用link和cut~~这道题是LCT模板题也没什么好说的。不过CCZ大爷有更快的做法,就是离线读入所有连边操作,然后建一棵树用链剖,判断输入是否合法就在线用并查集查询与维护。orzCCZ!

    代码:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #define inc(i,j,k) for(int i=j;i<=k;i++)
     5 #define maxn 50000
     6 using namespace std;
     7 
     8 int fa[maxn],ch[maxn][2],sm[maxn],v[maxn];bool rev[maxn];
     9 inline void update(int x){
    10     if(x==0)return; sm[x]=v[x];
    11     if(ch[x][0])sm[x]+=sm[ch[x][0]]; if(ch[x][1])sm[x]+=sm[ch[x][1]];
    12 }
    13 inline bool is_root(int x){
    14     if(x==0||fa[x]==0)return 1;
    15     return x!=ch[fa[x]][0]&&x!=ch[fa[x]][1];
    16 }
    17 inline void pushdown(int x){
    18     if(rev[x]){
    19         swap(ch[x][0],ch[x][1]); if(ch[x][0])rev[ch[x][0]]^=1; if(ch[x][1])rev[ch[x][1]]^=1; rev[x]^=1;
    20     }
    21 }
    22 void rotate(int x){
    23     if(x==0||is_root(x))return;
    24     int a1=fa[x],a2=fa[fa[x]],a3; bool b1=(x==ch[a1][1]),b2=(a1==ch[a2][1]),b3=is_root(a1); a3=ch[x][!b1];
    25     if(!b3)ch[a2][b2]=x; fa[x]=a2; ch[a1][b1]=a3; if(a3)fa[a3]=a1; ch[x][!b1]=a1; fa[a1]=x;
    26     update(a1); update(x); if(!b3)update(a2);
    27 }
    28 int dt[maxn],dts,y;
    29 void splay(int x){
    30     if(x==0)return; dts=0; y=x; while(! is_root(y))dt[++dts]=y,y=fa[y];
    31     dt[++dts]=y; while(dts)pushdown(dt[dts]),dts--;
    32     while(!is_root(x)){
    33         if(!is_root(fa[x]))((x==ch[fa[x]][1])^(fa[x]==ch[fa[fa[x]]][1]))?rotate(x):rotate(fa[x]);
    34         rotate(x);
    35     }
    36 }
    37 int access(int x){
    38     if(x==0)return 0; int t=0;
    39     while(x){splay(x); ch[x][1]=t; update(x); if(t)fa[t]=x; t=x; x=fa[x];}
    40     return t;
    41 }
    42 bool link(int x,int y){
    43     if(x==0||y==0)return 0; access(x); splay(x); rev[x]^=1; fa[x]=y; return 1;
    44 }
    45 int querysum(int x,int y){
    46     if(x==0||y==0)return 0; if(x==y)return v[x]; access(x); int a=access(y); splay(x); 
    47     if(x==a)return v[a]+sm[ch[a][1]];else return sm[x]+v[a]+sm[ch[a][1]];
    48 }
    49 void change(int x,int y){
    50     splay(x); v[x]=y; update(x);
    51 }
    52 int find(int x){
    53     access(x); splay(x); while(ch[x][0])x=ch[x][0]; return x;
    54 }
    55 int n,m; char s[20];
    56 int main(){
    57     //freopen("test.txt","r",stdin);
    58     scanf("%d",&n); inc(i,1,n)scanf("%d",&v[i]),fa[i]=0,ch[i][0]=ch[i][1]=rev[i]=0,sm[i]=v[i]; scanf("%d",&m);
    59     inc(i,1,m){
    60         int a,b; scanf("%s%d%d",s,&a,&b); 
    61         if(s[0]=='b'){if(find(a)==find(b))puts("no");else link(a,b),puts("yes");}
    62         if(s[0]=='p')change(a,b);
    63         if(s[0]=='e')if(find(a)!=find(b))puts("impossible");else printf("%d
    ",querysum(a,b));
    64     }
    65     return 0;
    66 }

    20160420

  • 相关阅读:
    IPV6地址中的%号什么意思
    比较分析C++、Java、Python、R语言的面向对象特征,这些特征如何实现的?有什么相同点?
    Linux 查看本机串口方法
    非对称加密与GPG/PGP
    bootstrap下拉三角
    bootstrap文本背景色
    bootstrap文本颜色
    bootstrap栅格系统响应式
    软件测试(一) 软件测试的阶段划分
    YoTube 视频如何下载
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5703246.html
Copyright © 2011-2022 走看看