zoukankan      html  css  js  c++  java
  • BZOJ 2959: 长跑 解题报告

    2959: 长跑

    Description

      某校开展了同学们喜闻乐见的阳光长跑活动。为了能“为祖国健康工作五十年”,同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑运动。一时间操场上熙熙攘攘,摩肩接踵,盛况空前。
      为了让同学们更好地监督自己,学校推行了刷卡机制。
      学校中有n个地点,用1到n的整数表示,每个地点设有若干个刷卡机。
      有以下三类事件:
      1、修建了一条连接A地点和B地点的跑道。
      2、A点的刷卡机台数变为了B。
      3、进行了一次长跑。问一个同学从A出发,最后到达B最多可以刷卡多少次。具体的要求如下:
      当同学到达一个地点时,他可以在这里的每一台刷卡机上都刷卡。但每台刷卡机只能刷卡一次,即使多次到达同一地点也不能多次刷卡。
      为了安全起见,每条跑道都需要设定一个方向,这条跑道只能按照这个方向单向通行。最多的刷卡次数即为在任意设定跑道方向,按照任意路径从A地点到B地点能刷卡的最多次数。

    Input

      输入的第一行包含两个正整数n,m,表示地点的个数和操作的个数。
      第二行包含n个非负整数,其中第i个数为第个地点最开始刷卡机的台数。
      接下来有m行,每行包含三个非负整数P,A,B,P为事件类型,A,B为事件的两个参数。
      最初所有地点之间都没有跑道。
      每行相邻的两个数之间均用一个空格隔开。表示地点编号的数均在1到n之间,每个地点的刷卡机台数始终不超过10000,P=1,2,3。

    Output

      输出的行数等于第3类事件的个数,每行表示一个第3类事件。如果该情况下存在一种设定跑道方向的方案和路径的方案,可以到达,则输出最多可以刷卡的次数。如果A不能到达B,则输出-1。


    思路:用LCT维护链的信息,用并查集进行缩点。

    注意到每次缩点后只有虚边连的边是不对的,所以在access时重新练一下虚边和询问的时候询问并查集的根就可以了,但是bzoj我还是没卡过去...


    Code:

    #include <cstdio>
    #include <cctype>
    #define ll long long
    #define fa par[now]
    #define ls ch[now][0]
    #define rs ch[now][1]
    const int N=150010;
    int read()
    {
        int x=0;char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) {x=x*10+c-'0';c=getchar();}
        return x;
    }
    int ch[N][2],par[N],tag[N],s[N],F[N],tot,tmp,n,m;
    ll sum[N],dat[N],Dat[N];
    int Find(int x){return F[x]=F[x]==x?x:Find(F[x]);}
    int identity(int now){return ch[fa][1]==now;}
    bool isroot(int now){return ch[fa][0]==now||ch[fa][1]==now;}
    void updata(int now){sum[now]=sum[ls]+sum[rs]+dat[now];}
    void Reverse(int now){tag[now]^=1,tmp=ls,ls=rs,rs=tmp;}
    void connect(int f,int now,int typ){ch[fa=f][typ]=now;}
    void pushdown(int now)
    {
        if(tag[now])
        {
            if(ls) Reverse(ls);
            if(rs) Reverse(rs);
            tag[now]^=1;
        }
    }
    void Rotate(int now)
    {
        int p=Find(fa),typ=identity(now);
        connect(p,ch[now][typ^1],typ);
        if(isroot(p)) connect(par[p],now,identity(p));
        else fa=Find(par[p]);
        connect(now,p,typ^1);
        updata(p),updata(now);
    }
    void splay(int now)
    {
        while(isroot(now)) s[++tot]=now,now=fa;s[++tot]=now;
        while(tot) pushdown(s[tot--]);now=s[1];
        for(;isroot(now);Rotate(now))
            if(isroot(fa))
                Rotate(identity(now)^identity(fa)?now:fa);
    }
    void access(int now)
    {
        for(int las=0;now;las=now,now=(fa=Find(fa)))
            splay(now),rs=las,updata(now);
    }
    void evert(int now){access(now),splay(now),Reverse(now);}
    int findroot(int now)
    {
        access(now);
        splay(now);
        while(ls) now=ls;
        return now;
    }
    void dfs(int now,int anc)
    {
        if(!now) return;
        F[now]=anc;
        dfs(ls,anc),dfs(rs,anc);
    }
    void link(int u,int v)
    {
        evert(u);
        if(findroot(v)!=u) par[u]=v;
        else dat[v]=sum[v],dfs(v,v),ch[v][0]=ch[v][1]=0;
    }
    void query(int u,int v)
    {
        evert(u);
        if(findroot(v)!=u) puts("-1");
        else printf("%lld
    ",sum[v]);
    }
    int main()
    {
        freopen("data.in","r",stdin);
        freopen("dew.out","w",stdout);
        n=read(),m=read();
        for(int i=1;i<=n;i++) F[i]=i,Dat[i]=sum[i]=dat[i]=read();
        for(int op,x,y,i=1;i<=m;i++)
        {
            op=read(),x=read(),y=read();
            if(op==1)
                link(Find(x),Find(y));
            else if(op==2)
            {
                int rt=Find(x);
                splay(rt);
                dat[rt]+=y-Dat[x];
                Dat[x]=y;
                updata(rt);
            }
            else
                query(Find(x),Find(y));
        }
        return 0;
    }
    

    2018.12.11

  • 相关阅读:
    仿苹果原生头部动画
    cookie VS sessionstorge VS localstorge
    require实现单页应用程序(SPA)
    物体position:absolute后设置left:50%发生的有趣小事
    C/JS_实现选择排序
    C/JS_实现冒泡排序
    C_求质数
    C/JS_二分法查找
    JS_高程6.面向对象的程序设计(2)创建对象_3 构造函数存在的问题
    CSS_常见布局
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10104352.html
Copyright © 2011-2022 走看看