zoukankan      html  css  js  c++  java
  • BZOJ 2157 旅行

    裸链剖。

    这大概是我第一份两百行左右的代码吧。

    然而我把题看错了233333333调了将近两天。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxv 100050
    #define maxe 300050
    using namespace std;
    struct edge
    {
        int v,w,nxt;
    }e[maxe];
    struct edge_
    {
        int u,v,w;
    }eg[maxe];
    char s[10];
    int n,x,y,z,g[maxv],nume=0,nume_=0,m;
    int dis[maxv],w[maxv],top[maxv],fath[maxv],size[maxv],son[maxv],cnt=0,tot=0,c[maxv];
    int ls[maxv<<2],rs[maxv<<2],lazy[maxv<<2],sum[maxv<<2],mx[maxv<<2],mn[maxv<<2],root;
    void addedge(int u,int v,int w)
    {
        e[++nume].v=v;
        e[nume].w=w;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void addedge_(int u,int v,int w)
    {
        eg[++nume_].u=u;
        eg[nume_].v=v;
        eg[nume_].w=w;
    }
    void dfs1(int x,int father)
    {
        size[x]=1;son[x]=0;
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v!=father)
            {
                fath[v]=x;dis[v]=dis[x]+1;
                dfs1(v,x);
                size[x]+=size[v];
                if (size[v]>size[son[x]]) son[x]=v;
            }
        }
    }
    void dfs2(int x,int father)
    {
        top[x]=father;w[x]=++cnt;
        if (son[x]!=0) dfs2(son[x],father); 
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v!=fath[x])
            {
                if (v!=son[x]) dfs2(v,v);
                c[w[v]]=e[i].w;
            }
        }
    }
    void pushup(int now)
    {
        sum[now]=sum[ls[now]]+sum[rs[now]];
        mx[now]=max(mx[ls[now]],mx[rs[now]]);
        mn[now]=min(mn[ls[now]],mn[rs[now]]);
    }
    void build(int &now,int left,int right)
    {
        now=++tot;lazy[now]=0;
        if (left==right)
        {
            sum[now]=mn[now]=mx[now]=c[left];
            return;
        }
        int mid=(left+right)>>1;
        build(ls[now],left,mid);
        build(rs[now],mid+1,right);
        pushup(now);
    }
    void pushdown(int now,int left,int right)
    {
        int r1,r2;
        if (lazy[now]==1)
        {
            sum[ls[now]]=-sum[ls[now]];sum[rs[now]]=-sum[rs[now]];
            r1=mn[ls[now]];r2=mx[ls[now]];mn[ls[now]]=-r2;mx[ls[now]]=-r1;
            r1=mn[rs[now]];r2=mx[rs[now]];mn[rs[now]]=-r2;mx[rs[now]]=-r1;
            lazy[ls[now]]^=1;lazy[rs[now]]^=1;
            lazy[now]=0;
        }
    }
    void modify(int now,int left,int right,int l,int r,int p,int type)
    {
        pushdown(now,left,right);
        if ((left==l) && (right==r))
        {
            if (type==1)
            {
                sum[now]=p;
                mx[now]=p;mn[now]=p;
                return;
            }
            else
            {
                lazy[now]^=1;
                sum[now]=-sum[now];
                int r1,r2;r1=mn[now];r2=mx[now];
                mn[now]=-r2;mx[now]=-r1;
                return;
            }
        }
        int mid=(left+right)>>1;
        if (r<=mid) modify(ls[now],left,mid,l,r,p,type);
        else if (l>=mid+1) modify(rs[now],mid+1,right,l,r,p,type);
        else
        {
            modify(ls[now],left,mid,l,mid,p,type);
            modify(rs[now],mid+1,right,mid+1,r,p,type);
        }
        pushup(now);
    }
    int ask(int now,int left,int right,int l,int r,int type)
    {
        pushdown(now,left,right);
        if ((left==l) && (right==r))
        {
            if (type==1) return sum[now];
            else if (type==2) return mx[now];
            else return mn[now];
        }
        int mid=(left+right)>>1;
        if (r<=mid) return ask(ls[now],left,mid,l,r,type);
        else if (l>=mid+1) return ask(rs[now],mid+1,right,l,r,type);
        else
        {
            if (type==1) return ask(ls[now],left,mid,l,mid,type)+ask(rs[now],mid+1,right,mid+1,r,type);
            else if (type==2) return max(ask(ls[now],left,mid,l,mid,type),ask(rs[now],mid+1,right,mid+1,r,type));
            else return min(ask(ls[now],left,mid,l,mid,type),ask(rs[now],mid+1,right,mid+1,r,type));
        }
    }
    void work()
    {
        scanf("%d%d",&x,&y);
        x++;y++;
        int f1=top[x],f2=top[y];
        if (s[0]=='N')
        {
            while (f1!=f2)
            {
                if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);}
                modify(root,1,cnt,w[f1],w[x],0,2);
                x=fath[f1];f1=top[x];
            }
            if (x!=y)
            {
                if (dis[x]>dis[y]) swap(x,y);
                modify(root,1,cnt,w[son[x]],w[y],0,2);
            }
        }
        else if (s[0]=='S')
        {
            int ans=0;
            while (f1!=f2)
            {
                if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);}
                ans+=ask(root,1,cnt,w[f1],w[x],1);
                x=fath[f1];f1=top[x];
            }
            if (x!=y)
            {
                if (dis[x]>dis[y]) swap(x,y);
                ans+=ask(root,1,cnt,w[son[x]],w[y],1);
            }
            printf("%d
    ",ans);
        }
        else if ((s[0]=='M') && (s[1]=='A'))
        {
            int ans=0xefefefef;
            while (f1!=f2)
            {
                if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);}
                ans=max(ans,ask(root,1,cnt,w[f1],w[x],2));
                x=fath[f1];f1=top[x];
            }
            if (x!=y)
            {
                if (dis[x]>dis[y]) swap(x,y);
                ans=max(ans,ask(root,1,cnt,w[son[x]],w[y],2));
            }
            printf("%d
    ",ans);
        }
        else
        {
            int ans=0x3f3f3f3f;
            while (f1!=f2)
            {
                if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);}
                ans=min(ans,ask(root,1,cnt,w[f1],w[x],3));
                x=fath[f1];f1=top[x];
            }
            if (x!=y)
            {
                if (dis[x]>dis[y]) swap(x,y);
                ans=min(ans,ask(root,1,cnt,w[son[x]],w[y],3));
            }
            printf("%d
    ",ans);
        }
    }
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n-1;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            x++;y++;
            addedge(x,y,z);
            addedge(y,x,z);
            addedge_(x,y,z);
        }
        dfs1(1,1);
        dfs2(1,1);
        build(root,1,cnt);
        scanf("%d",&m);
        for (int i=1;i<=m;i++)
        {
            scanf("%s",s);
            if (s[0]=='C')
            {
                scanf("%d%d",&x,&y);
                int u,v;
                u=eg[x].u;v=eg[x].v;
                if (fath[u]==v) modify(root,1,cnt,w[u],w[u],y,1);
                else modify(root,1,cnt,w[v],w[v],y,1);
            }
            else work();
        }
        return 0;
    }
  • 相关阅读:
    模板库
    LCT小结
    BZOJ1502: [NOI2005]月下柠檬树
    技术资料分享
    ORM介紹及ORM優點、缺點
    依賴注入入門——Unity(二)
    面向切面編程入門(一)
    依賴注入入門——Unity(一)
    WCF、.Net Remoting、Web Service概念及区别
    深入设计模式(四)——建造者模式
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5669345.html
Copyright © 2011-2022 走看看