bzoj1180: [CROATIAN2009]OTOCI(lct)
来源:互联网 发布:unity3d与ar 编辑:程序博客网 时间:2024/06/08 10:13
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操作对应的输出,每个一行。
Sample Input
5
4 2 4 5 6
10
excursion 1 1
excursion 1 2
bridge 1 2
excursion 1 2
bridge 3 4
bridge 3 5
excursion 4 5
bridge 1 3
excursion 2 4
excursion 2 5
Sample Output
4
impossible
yes
6
yes
yes
15
yes
15
16
题解:动态树。
统计和时在access()和rotate()里面更新即可。
(三目运算符一定要加括号!!!!)
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<cmath>using namespace std;typedef long long ll;const int Maxn=3e4+50;inline ll read(){ char ch=getchar();int i=0,f=1; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){i=(i<<3)+(i<<1)+ch-'0';ch=getchar();} return i*f;}struct node{ node *lc,*rc,*fa; ll w,sum; int tag; node(const ll &v):lc(NULL),rc(NULL),fa(NULL),w(v),sum(v),tag(0){}; inline void upt() { sum=((lc?lc->sum:0)+(rc?rc->sum:0))+w; }}*tr[Maxn];int n,Q;inline bool isroot(node *x){ return !x->fa||(x->fa->lc!=x&&x->fa->rc!=x);}inline void downdate(node *x){ if(x->tag) { swap(x->lc,x->rc); if(x->lc)x->lc->tag^=1; if(x->rc)x->rc->tag^=1; x->tag=0; }}inline void rotate(node *x){ node *y=x->fa,*z=y->fa; if(z&&!isroot(y)) ((z->lc==y)?(z->lc):(z->rc))=x; x->fa=z,y->fa=x; node *b=y->lc==x?x->rc:x->lc; b?b->fa=y:0; if(y->lc==x)x->rc=y,y->lc=b; else x->lc=y,y->rc=b; y->upt(),x->upt(); }inline bool which(node *x){ return x->fa->lc==x;}inline void splay(node *x){ static node *que[Maxn]; int qn=0; que[qn=1]=x; for(node *y=x;!isroot(y);y=y->fa)que[++qn]=y->fa; for(int i=qn;i>=1;i--)downdate(que[i]); while(!isroot(x)) { if(!isroot(x->fa)) { if(which(x)^which(x->fa))rotate(x); else rotate(x->fa); } rotate(x); }}inline void access(node *x){ for(node *y=NULL;x;y=x,x=x->fa) { splay(x);x->rc=y; if(y)y->fa=x; x->upt(); }}inline void makeroot(node *x){ access(x); splay(x); x->tag^=1;}inline node* findroot(node *x){ access(x);splay(x); while(x->lc)x=x->lc; return x;}inline void link(node *x,node *y){ makeroot(x); x->fa=y;}int main(){ n=read(); for(int i=1;i<=n;i++) { ll x=read(); tr[i]=new node(x); } Q=read(); while(Q--) { static char ch[20]; scanf("%s",ch+1); if(ch[1]=='b') { int x=read(),y=read(); makeroot(tr[x]); if(findroot(tr[y])==tr[x])puts("no"); else puts("yes"),link(tr[x],tr[y]); } else if(ch[1]=='p') { int x=read(); ll val=read(); makeroot(tr[x]); tr[x]->w=val; tr[x]->upt(); } else { int x=read(),y=read(); makeroot(tr[x]); if(findroot(tr[y])!=tr[x])puts("impossible"); else { makeroot(tr[x]); access(tr[y]); splay(tr[y]); printf("%lld\n",tr[y]->sum); } } } return 0;}
0 0
- 【bzoj1180】【CROATIAN2009】【OTOCI】【lct】
- [BZOJ1180][CROATIAN2009][LCT]OTOCI
- bzoj1180: [CROATIAN2009]OTOCI(lct)
- [BZOJ1180][CROATIAN2009]OTOCI(LCT)
- bzoj1180 [CROATIAN2009]OTOCI(详解LCT操作)
- BZOJ1180 [CROATIAN2009]OTOCI
- bzoj1180: [CROATIAN2009]OTOCI
- [BZOJ1180] [CROATIAN2009]OTOCI
- [BZOJ1180][CROATIAN2009]OTOCI
- 【bzoj1180】[CROATIAN2009]OTOCI
- bzoj1180: [CROATIAN2009]OTOCI
- BZOJ1180: [CROATIAN2009]OTOCI
- 【bzoj1180】[CROATIAN2009]OTOCI
- 【bzoj1180】OTOCI LCT
- BZOJ1180 OTOCI(LCT动态树)
- [bzoj1180][CROATIAN2009]OTOCI Link-Cut-Tree
- bzoj 1180 [CROATIAN2009]OTOCI - LCT
- 【BZOJ 1180】[CROATIAN2009]OTOCI LCT
- C编程经验总结4
- js刷新页面的几种常用方法
- Activemq 常见的一些问题 心得
- 什么时候用接口,什么时候用抽象类?
- 家园 codevs1034 ctsc1999 最大流
- bzoj1180: [CROATIAN2009]OTOCI(lct)
- Python3 (入门5) 类
- bzoj 1610: [Usaco2008 Feb]Line连线游戏
- c++第三次实验
- Symbol数据类型
- 【USACO题库】2.3.3 Zero Sum和为零
- Java命名规范
- leetcode 38. Count and Say
- 博为峰Java技术文章 ——JavaSE Swing 文件选取器JFileChooser(1)