2843: 极地旅行社

来源:互联网 发布:靓心阁优化门窗 编辑:程序博客网 时间:2024/06/08 07:00

题目链接

题解:

对于第一个操作我们可以用并查集来搞,

然后离线+树链剖分+树状数组,

感觉不是很难想,后来看了看题解发现全都用lct,蒟蒻lct太弱QWQ,只好乱搞了。

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int N=100010;const int M=30010;int n,m;int v[M],f[M];char s[N],s1[20];int x[N],y[N];struct node{    int x,y,next;}sa[N*2];int len=1,first[M];bool tf[M];int bit[N];int lowbit(int x){    return x&-x;}void add(int x,int y){    while(x<=n)    {        bit[x]+=y;        x+=lowbit(x);    }}int getsum(int x){    int sum=0;    while(x>=1)    {        sum+=bit[x];        x-=lowbit(x);    }    return sum;}int findfa(int x){    int a=x,c;    while(x!=f[x])x=f[x];    while(x!=(c=f[a]))f[a]=x,a=c;    return x;}void ins(int x,int y){    len++;    sa[len].x=x;    sa[len].y=y;    sa[len].next=first[x];    first[x]=len;}int dep[M],son[M],size[M],fa[M];void dfs1(int x,int pa){    size[x]=1;    fa[x]=pa;    for(int i=first[x];i!=-1;i=sa[i].next)    {        int y=sa[i].y;        if(y!=pa)        {            dep[y]=dep[x]+1;            dfs1(y,x);            size[x]+=size[y];            if(size[son[x]]<size[y]) son[x]=y;        }    }}int top[M],id[M],idn=0;void dfs2(int x,int tp){    //printf("%d %d\n",x,tp);    //system("pause\n");    top[x]=tp;    id[x]=++idn;    add(id[x],v[x]);    if(son[x]) dfs2(son[x],tp);    for(int i=first[x];i!=-1;i=sa[i].next)    {        int y=sa[i].y;        if(y!=fa[x]&&y!=son[x])        {            dfs2(y,y);        }    }}int solve(int x,int y){    /*int tx=top[x],ty=top[y],s=0;    while(tx!=ty)    {        if(dep[x]>dep[y]) swap(x,y),swap(tx,ty);        s+=getsum(id[y])-getsum(id[ty]-1);        y=fa[ty];ty=top[y];    }    if(dep[x]>dep[y]) swap(x,y);    s+=getsum(id[y])-getsum(id[x]-1);    return s;*/    int a=top[x],b=top[y],c,s=0;    while(a!=b){        if(dep[a]<dep[b]){            s+=getsum(id[y])-getsum(id[b]-1);            y=fa[b];b=top[y];        }else{            s+=getsum(id[x])-getsum(id[a]-1);            x=fa[a];a=top[x];        }    }    if(dep[x]<dep[y])s+=getsum(id[y])-getsum(id[x]-1);    else s+=getsum(id[x])-getsum(id[y]-1);    return s;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)f[i]=i;    for(int i=1;i<=n;i++) scanf("%d",&v[i]);    memset(first,-1,sizeof(first));    scanf("%d",&m);    for(int i=1;i<=m;i++)    {        scanf("%s",s1);        scanf("%d%d",&x[i],&y[i]);        s[i]=s1[0];        if(s1[0]=='b')        {            int tx=findfa(x[i]),ty=findfa(y[i]);            if(tx!=ty)            {                f[tx]=ty;                ins(x[i],y[i]);ins(y[i],x[i]);            }        }    }    memset(bit,0,sizeof(bit));//  for(int i=1;i<=n;i++) printf("%d\n",fa[i]);    for(int i=1;i<=n;i++)    if(!tf[findfa(i)])    {        tf[findfa(i)]=true;        dfs1(i,0);dfs2(i,i);//printf("@\n");printf("!");    }//  printf("!");    for(int i=1;i<=n;i++) f[i]=i;    for(int i=1;i<=m;i++)    {        if(s[i]=='b')        {            int tx=findfa(x[i]),ty=findfa(y[i]);            if(tx!=ty) f[tx]=ty,printf("yes\n");            else printf("no\n");        }        else if(s[i]=='p')        {            int yu=y[i]-v[x[i]];            v[x[i]]+=yu;            add(id[x[i]],yu);        }        else        {            int tx=findfa(x[i]),ty=findfa(y[i]);            if(tx!=ty)printf("impossible\n");            else printf("%d\n",solve(x[i],y[i]));        }    }}