zoukankan      html  css  js  c++  java
  • BZOJ 3999 旅游

    。。。。。。。好长啊。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxv 50050
    #define maxe 100500
    #define inf 2000000000
    using namespace std;
    int n,m,val[maxv],x,y,z,g[maxv],nume=1,fath[maxv],top[maxv],w[maxv],fw[maxv],son[maxv],size[maxv],dis[maxv],times=0;
    int tot=0,root,ls[maxv<<2],rs[maxv<<2],mn[maxv<<2],mx[maxv<<2],fr[maxv<<2],ba[maxv<<2],lazy[maxv<<2];
    int r1,r2,r3;
    struct edge
    {
        int v,nxt;
    }e[maxe];
    int read()
    {
        char ch;int data=0;
        while (ch<'0' || ch>'9') ch=getchar();
        while (ch>='0' && ch<='9')
        {
            data=data*10+ch-'0';
            ch=getchar();
        }
        return data;
    }
    void addedge(int u,int v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void dfs1(int x)
    {
        size[x]=1;son[x]=0;
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v!=fath[x])
            {
                fath[v]=x;dis[v]=dis[x]+1;
                dfs1(v);
                size[x]+=size[v];
                if (size[son[x]]<size[v]) son[x]=v;
            }
        }
    }
    void dfs2(int x,int father)
    {
          w[x]=++times;fw[times]=x;top[x]=father;
          if (son[x]) dfs2(son[x],father);
          for (int i=g[x];i;i=e[i].nxt)
          {
               int v=e[i].v;
               if ((v!=fath[x]) && (v!=son[x]))
                   dfs2(v,v);
          }
    }
    void reset()
    {
        r1=inf;r2=0;r3=0;
    }
    void pushup(int now)
    {
          mx[now]=max(mx[ls[now]],mx[rs[now]]);
          mn[now]=min(mn[ls[now]],mn[rs[now]]);
          fr[now]=max((mx[rs[now]]-mn[ls[now]]),max(fr[ls[now]],fr[rs[now]]));
          ba[now]=max((mx[ls[now]]-mn[rs[now]]),max(ba[ls[now]],ba[rs[now]]));
    }
    void pushdown(int now,int left,int right)
    {
        if (!lazy[now]) return;
        lazy[ls[now]]+=lazy[now];lazy[rs[now]]+=lazy[now];
        mx[ls[now]]+=lazy[now];mx[rs[now]]+=lazy[now];
        mn[ls[now]]+=lazy[now];mn[rs[now]]+=lazy[now];
        lazy[now]=0;
    }
    void build(int &now,int left,int right)
    {
        now=++tot;
        if (left==right) {mn[now]=mx[now]=val[fw[left]];fr[now]=ba[now]=0;return;}
        int mid=(left+right)>>1;
        build(ls[now],left,mid);
        build(rs[now],mid+1,right);
        pushup(now);
    }
    void 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) r3=max(r3,mx[now]-r1);else r3=max(r3,r2-mn[now]);
            if (type==1) r3=max(r3,fr[now]);else r3=max(r3,ba[now]);
            r1=min(r1,mn[now]);r2=max(r2,mx[now]);
            return;
        }
        int mid=(left+right)>>1;
        if (r<=mid) ask(ls[now],left,mid,l,r,type);
        else if (l>=mid+1) ask(rs[now],mid+1,right,l,r,type);
        else
        {
            ask(ls[now],left,mid,l,mid,type);
            ask(rs[now],mid+1,right,mid+1,r,type);
        }
    }
    void modify(int now,int left,int right,int l,int r,int x)
    {
        pushdown(now,left,right);
        if ((left==l) && (right==r))
        {
            lazy[now]+=x;mn[now]+=x;mx[now]+=x;
            return;
        }
        int mid=(left+right)>>1;
        if (r<=mid) modify(ls[now],left,mid,l,r,x);
        else if (l>=mid+1) modify(rs[now],mid+1,right,l,r,x);
        else 
        {
            modify(ls[now],left,mid,l,mid,x);
            modify(rs[now],mid+1,right,mid+1,r,x);
        }
        pushup(now);
    }
    int lca(int x,int y)
    {
        int f1=top[x],f2=top[y];
        while (f1!=f2)
        {
            if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);}
            x=fath[f1];f1=top[x];
        }
        if (dis[x]<dis[y]) return x;else return y;
    }
    void find_answer(int x,int y,int z)
    {
        int ans=0,t=lca(x,y),mn,mx;
        int f1=top[x],f2=top[y];
        mn=inf;mx=0;
        while (f1!=top[t])
        {
              reset();ask(root,1,n,w[f1],w[x],2);
              ans=max(ans,r2-mn);ans=max(ans,r3);mn=min(mn,r1);
             x=fath[f1];f1=top[x];
        }
        reset();ask(root,1,n,w[t],w[x],2);
        ans=max(ans,r2-mn);ans=max(ans,r3);mn=min(mn,r1);
        while (f2!=top[t])
        {
            reset();ask(root,1,n,w[f2],w[y],1);
            ans=max(ans,mx-r1);ans=max(ans,r3);mx=max(mx,r2);
            y=fath[f2];f2=top[y];
        }
        reset();ask(root,1,n,w[t],w[y],1);
        ans=max(ans,mx-r1);ans=max(ans,r3);mx=max(mx,r2);
        ans=max(ans,mx-mn);
        printf("%d
    ",ans);
    }
    void modify_tree(int x,int y,int z)
    {
          int f1=top[x],f2=top[y];
          while (f1!=f2)
          {
             if (dis[f1]<dis[f2]) {swap(f1,f2);swap(x,y);}
             modify(root,1,n,w[f1],w[x],z);
             x=fath[f1];f1=top[x];
          }
          if (dis[x]>dis[y]) swap(x,y);
         modify(root,1,n,w[x],w[y],z);
    }
    int main()
    {
         n=read();
         for (int i=1;i<=n;i++) val[i]=read();
        for (int i=1;i<=n-1;i++)
        {
            x=read();y=read();
            addedge(x,y);addedge(y,x);
        }
        dfs1(1);
        dfs2(1,1);
        build(root,1,n);
        m=read();
        for (int i=1;i<=m;i++)
        {
            x=read();y=read();z=read();
            find_answer(x,y,z);
            modify_tree(x,y,z);
        }
        return 0;
    }
  • 相关阅读:
    如何将数组初始化为全0?
    什么是优先级队列(priority queue)?
    C语言中指针的指针是如何工作的?
    什么是队列(Queue)?
    理解*ptr++
    【Luogu】P4172水管局长(LCT)
    【Luogu】P4159迷路(矩阵优化)
    【Luogu】P3971Alice And Bob(贪心)
    【Luogu】P3211XOR和路径(高斯消元)
    【Luogu】P2445动物园(最大流)
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6134477.html
Copyright © 2011-2022 走看看