【BZOJ2843&&1180】极地旅行社,LCT练习

来源:互联网 发布:国际条约集数据库 编辑:程序博客网 时间:2024/04/27 18:01

传送门-P2843
(1180是权限题,所以就不放了)
写在前面:为什么BZOJ上LCT好多都是权限题(╯‵□′)╯︵┻━┻
思路:判断联通用findroot函数(洞穴探测里已经说过了);修改x的操作可以把x旋转到所在的splay的根上来,再修改;查询的话把x,y分别access到同一棵splay上,splay操作后求值即可
注意:无
代码:

#include<bits/stdc++.h>#define pd(i) (i>='0'&&i<='9')using namespace std;int n,m,x,y;int stacks[30010];char s[10];struct tree{    int fa,ch[2],sum,data;    bool lazy;}a[200010];int in(){    int t=0;    char ch=getchar();    while (!pd(ch)) ch=getchar();    while (pd(ch)) t=(t<<3)+(t<<1)+ch-'0',ch=getchar();    return t;}void ct(int x){    a[x].sum=a[a[x].ch[0]].sum+a[a[x].ch[1]].sum+a[x].data;}#define isroot(x) (a[a[x].fa].ch[0]!=x&&a[a[x].fa].ch[1]!=x)void pushdown(int x){    if (!a[x].lazy) return;    a[a[x].ch[0]].lazy^=1;    a[a[x].ch[1]].lazy^=1;    swap(a[x].ch[0],a[x].ch[1]);    a[x].lazy=0;}void rorate(int x,bool mk){    int y=a[x].fa;    a[x].fa=a[y].fa;    if (!isroot(y))    {        if (a[a[y].fa].ch[0]==y) a[a[y].fa].ch[0]=x;        else a[a[y].fa].ch[1]=x;    }    a[y].ch[!mk]=a[x].ch[mk];    a[a[x].ch[mk]].fa=y;    a[x].ch[mk]=y;    a[y].fa=x;    ct(y);ct(x);}void splay(int x){    int y,cnt=0,k=x;    stacks[++cnt]=k;    while (!isroot(k)) k=a[k].fa,stacks[++cnt]=k;    for (int i=cnt;i;i--) pushdown(stacks[i]);    while (!isroot(x))    {        y=a[x].fa;        if (isroot(y))        {            if (a[y].ch[0]==x) rorate(x,1);            else rorate(x,0);        }        else if (a[a[y].fa].ch[0]==y)        {            if (a[y].ch[0]==x) rorate(y,1);            else rorate(x,0);            rorate(x,1);        }        else        {            if (a[y].ch[1]==x) rorate(y,0);            else rorate(x,1);            rorate(x,0);        }    }}void access(int x){    for (int y=0;x;y=x,x=a[x].fa)        splay(x),        a[x].ch[1]=y,        ct(x);}void link(int x,int y){    access(x);    splay(x);    a[x].lazy^=1;    a[x].fa=y;}void cut(int x,int y){    access(x);    splay(x);    a[x].lazy^=1;    access(y);    splay(y);    a[x].fa=a[y].ch[0]=0;    ct(y);}int findroot(int x){    access(x);    splay(x);    while (a[x].ch[0]) x=a[x].ch[0];    return x;}main(){    n=in();    for (int i=1;i<=n;i++)        a[i].data=in(),        a[i].sum=a[i].data;    scanf("%d",&m);    while (m--)    {        scanf("%s",s);        x=in();y=in();        if (s[0]=='b')        {            if (findroot(x)==findroot(y)) puts("no");            else puts("yes"),link(x,y);        }        else if (s[0]=='p')        {            splay(x);            a[x].sum+=(y-a[x].data);            a[x].data=y;        }        else        {            if (findroot(x)!=findroot(y)) puts("impossible");            else                access(x),                splay(x),                a[x].lazy^=1,                access(y),                splay(y),                printf("%d\n",a[y].sum);        }    }}
0 0
原创粉丝点击