首页 > 代码库 > BZOJ 1180: [CROATIAN2009]OTOCI [LCT]
BZOJ 1180: [CROATIAN2009]OTOCI [LCT]
1180: [CROATIAN2009]OTOCI
Time Limit: 50 Sec Memory Limit: 162 MBSubmit: 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]
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。