首页 > 代码库 > BZOJ 1180: [CROATIAN2009]OTOCI [LCT]

BZOJ 1180: [CROATIAN2009]OTOCI [LCT]

1180: [CROATIAN2009]OTOCI

Time Limit: 50 Sec  Memory Limit: 162 MB
Submit: 961  Solved: 594
[Submit][Status][Discuss]

Description

给出n个结点以及每个点初始时对应的权值wi。起始时点与点之间没有连边。有3类操作: 1、bridge A B:询问结点A与结点B是否连通。如果是则输出“no”。否则输出“yes”,并且在结点A和结点B之间连一条无向边。 2、penguins A X:将结点A对应的权值wA修改为X。 3、excursion A B:如果结点A和结点B不连通,则输出“impossible”。否则输出结点A到结点B的路径上的点对应的权值的和。给出q个操作,要求在线处理所有操作。数据范围:1<=n<=30000, 1<=q<=300000, 0<=wi<=1000。

Input

第一行包含一个整数n(1<=n<=30000),表示节点的数目。第二行包含n个整数,第i个整数表示第i个节点初始时对应的权值。第三行包含一个整数q(1<=n<=300000),表示操作的数目。以下q行,每行包含一个操作,操作的类别见题目描述。任意时刻每个节点对应的权值都是1到1000的整数。

Output

输出所有bridge操作和excursion操作对应的输出,每个一行。


 

单点修改,链查询.....

貌似我还没写过splay的单点修改,好像只要修改t[x].w就可以了

链查询就是M A s得到x到y的链的Splay然后t[y].sum行了

 

注意:单点修改后别忘splay一下,这时候Access无所谓

Access的时候一定要更新,因为重新设置了rc嘛!!!!

 

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>using namespace std;#define pa t[x].fa#define lc t[x].ch[0]#define rc t[x].ch[1]const int N=3e4+5;inline int read(){    char c=getchar();int x=0,f=1;    while(c<0||c>9){if(c==-)f=-1;c=getchar();}    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}    return x*f;}struct node{    int ch[2],fa,rev;    int sum,w;}t[N];inline void update(int x){t[x].sum=t[lc].sum+t[rc].sum+t[x].w;}inline int wh(int x){return t[pa].ch[1]==x;}inline int isRoot(int x){return t[pa].ch[0]!=x&&t[pa].ch[1]!=x;}inline void pushDown(int x){    if(t[x].rev){        t[lc].rev^=1;        t[rc].rev^=1;        swap(lc,rc);        t[x].rev=0;    }}inline void rotate(int x){    int f=t[x].fa,g=t[f].fa,c=wh(x);    if(!isRoot(f)) t[g].ch[wh(f)]=x;t[x].fa=g;    t[f].ch[c]=t[x].ch[c^1];t[t[f].ch[c]].fa=f;    t[x].ch[c^1]=f;t[f].fa=x;    update(f);update(x);}int st[N],top;inline void splay(int x){    top=0;st[++top]=x;    for(int i=x;!isRoot(i);i=t[i].fa) st[++top]=t[i].fa;    for(int i=top;i>=1;i--) pushDown(st[i]);        for(;!isRoot(x);rotate(x))        if(!isRoot(pa)) rotate(wh(x)==wh(pa)?pa:x);}inline void Access(int x){    for(int y=0;x;y=x,x=pa){        splay(x);        rc=y;        update(x);    }}inline void MakeRoot(int x){    Access(x);    splay(x);    t[x].rev^=1;}inline int FindRoot(int x){    Access(x);    splay(x);    while(lc) x=lc;    return x;}inline void Link(int x,int y){    MakeRoot(x);    t[x].fa=y;    splay(x);}int n,Q,x,y;char s[N];int main(){    //freopen("in.txt","r",stdin);    n=read();    for(int i=1;i<=n;i++) t[i].w=t[i].sum=read();    Q=read();    while(Q--){        scanf("%s",s);x=read();y=read();        if(s[0]==b){            if(FindRoot(x)==FindRoot(y)) puts("no");            else puts("yes"),Link(x,y);        }else if(s[0]==p){            t[x].w=y;            //Access(x);            splay(x);        }else{            if(FindRoot(x)!=FindRoot(y)) puts("impossible");            else{                MakeRoot(x);Access(y);splay(y);                printf("%d\n",t[y].sum);            }        }    }}

 

BZOJ 1180: [CROATIAN2009]OTOCI [LCT]