zoukankan      html  css  js  c++  java
  • ZOJ3724 树状数组+离线处理

    题目看似一个最短路问题,仔细分析一下会发现,问题可以转化为求区间最值问题。区间最值一直递增或者递减的话,可以直接用树状数组实现。

    询问可以分为两种情况:

    U>V 这是比较复杂的情况,然后路径只有一种:U->u->v->V,其中u>=U ,v<=V。u-v是选择的一条小路。

    然后可以从后往前处理,从n到1枚举起点。这样能够保证处理到U的时候,u->v这些边都已经被处理了。处理U的时候,先把u=U的边用于更新[v,i]这段区间,因为所有在[v,i]内的V都可能受到u->v这条边的影响。边权为Sum[U]-Sum[v]+edge[u->v].cost。更新完成好,进行查询操作。单点查询V,区间[V,U]的最小值-(Sum[U]-Sum[V])就是答案。

    U<V是比较好处理的情况。差不多的思想。从1到n枚举终点,进行离线处理。

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <sstream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    using namespace std ;
    
    #define SZ(x)  (int)((x).size())
    #define For(i , forN) for(int i = 0 ; i < (forN) ; ++i)
    #define Fori(i,si,forN) for(int i=(si);i < (forN); i++)
    #define sf scanf
    #define pf printf
    #define pb push_back
    #define showCase(x) printf("Case %d: ",(x));
    
    
    //
    #define lc l,mid,x<<1
    #define rc mid+1,r,x<<1|1
    #define cmax(x,y) ((x)>(y)?(x):(y))
    #define cmin(x,y) ((x)>(y)?(y):(x))
    #define mp(x,y) make_pair((x),(y))
    #define lowbit(x) ((x)&(-x))
    
    #define DEBUG
    
    #ifdef DEBUG
    #define Dctn(x) cout<<#x<<"="<<x<<"  "
    #define Dct(x) cout<<x<<" "
    #define Dl cout<<endl
    #endif
    
    //
    typedef pair < int ,int > pii;
    typedef pair < int , pii > piii;
    typedef vector < int > vi;
    typedef vector < pii > vpii;
    typedef long long LL;
    
    const LL Inf = (~0ull)>>1;
    const int Maxn=110000;
    vpii quest[Maxn][2];
    vpii E[Maxn][2];//j表示是否以i为终点的边,第三维表示{起点,距离,问题的编号}。
    LL sum[Maxn];
    int n,m,Q;
    LL node[Maxn],Res[Maxn<<2];
    
    void updateBIT(int x,int val)
    {
        while(x)
        {
            node[x]=cmin(node[x],val);
            x-=lowbit(x);
        }
    }
    
    LL queryBIT(int x)
    {
        LL res=Inf;
        while(x<=n)
        {
            res=cmin(res,node[x]);
            x+=lowbit(x);
        }
        return res;
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            int tmp,u,v;
            Fori(i,2,n+1)
            {
                sf("%d",&tmp);
                sum[i]=sum[i-1]+tmp;
                E[i][0].clear();E[i][1].clear();
                quest[i][0].clear();    quest[i][1].clear();
            }
            For(i,m)
            {
                sf("%d%d%d",&u,&v,&tmp);
                if(u<v)
                E[v][1].pb(mp(u,tmp));
                else
                E[u][0].pb(mp(v,tmp));
            }
            sf("%d",&Q);
            For(i,Q)
            {
                sf("%d%d",&u,&v);
                if(u<v)         quest[v][1].pb(mp(u,i));
                else if(u==v)   Res[i]=0;
                else            quest[u][0].pb(mp(v,i));
            }
            Fori(i,1,n+1)   node[i]=Inf;
            for(int i=n;i>=1;i--)
            {
                For(j,SZ(E[i][0]))
                {
                    v=E[i][0][j].first;
                    updateBIT(n-v+1,sum[i]-sum[v]+E[i][0][j].second);
                }
                For(j,SZ(quest[i][0]))
                {
                    v=quest[i][0][j].first;
                    Res[quest[i][0][j].second]=queryBIT(n-v+1)-(sum[i]-sum[v]);
                }
            }
            Fori(i,1,n+1)   node[i]=0;
            Fori(i,1,n+1)
            {
                For(j,SZ(E[i][1]))
                {
                    u=E[i][1][j].first;
                    updateBIT(u,E[i][1][j].second-(sum[i]-sum[u]));
                }
                For(j,SZ(quest[i][1]))
                {
                    u=quest[i][1][j].first;
                    Res[quest[i][1][j].second]=sum[i]-sum[u]+queryBIT(u);
                }
            }
            For(i,Q)    pf("%lld
    ",Res[i]);
        }
        return 0;
    }
  • 相关阅读:
    转“C++之文件IO操作流”
    编译过程的一些小知识——#pragma once与 #ifndef的区别以及介绍
    编译过程的一些小知识——内部连接与外部连接
    VC MFC如何使用Console输出调试信息..
    windows 下ping命令,t选项
    电力间隔定义
    这样的要求不过分
    拾零之 :if 判断顺序的问题
    CMarkup 解析XML
    XinZhou housing mobile phone
  • 原文地址:https://www.cnblogs.com/CooCoo/p/3236556.html
Copyright © 2011-2022 走看看