zoj 3742 Delivery 好题

Delivery

题目还是自己看吧 - -!

   看似图论,实际上是一个考察思维以及数据结构的题。

 

  我们对于先前和向后的边分别进行统计。

  对询问离线。

  小边按照左端点从大到小排序。

  

  1.对于向后的边,询问按照出发点从大到小排序。比如询问有

  2 3

  3 4

  我们先对3 4进行计算。把向后的小边(3,5) ,(3,4) 用线段树维护,分别在线段树的位置4,5中插入用该边时可以优化的值。询问3 4时,我们发现出发点3以及后面的小边都加进了线段树中,直接询问线段树区间 [3,4]的最小值进行计算即可。注意一下可能加入了边之后比不加边更差的情况。

  然后再对2 3进行计算,这次把小边(2,4)添加到线段树中,查询区间[2,4]的最小值即可。

 

  2.对于向前的边,询问按照出发点从大到小排序。

  同样跟1差不多,不过这次询问(x,y)时询问的是区间[1,y]。

  

  具体可以看代码。

 

#include <set>
#include <map>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define debug puts("here")
#define rep(i,n) for(int i=0;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define REP(i,a,b) for(int i=a;i<=b;i++)
#define foreach(i,vec) for(unsigned i=0;i<vec.size();i++)
#define pb push_back
#define RD(n) scanf("%d",&n)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define RD4(x,y,z,w) scanf("%d%d%d%d",&x,&y,&z,&w)
#define All(vec) vec.begin(),vec.end()
#define MP make_pair
#define PII pair<int,int>
#define PQ priority_queue
#define cmax(x,y) x = max(x,y)
#define cmin(x,y) x = min(x,y)
#define Clear(x) memset(x,0,sizeof(x))
#define lson rt<<1
#define rson rt<<1|1

/*

#pragma comment(linker, "/STACK:1024000000,1024000000")

int size = 256 << 20; // 256MB
char *p = (char*)malloc(size) + size;
__asm__("movl %0, %%esp\n" :: "r"(p) );

*/

char IN;
bool NEG;
int OUT[15],top;
inline void Int(int &x){
    NEG = 0;
    while(!isdigit(IN=getchar()))
        if(IN=='-')NEG = 1;
    x = IN-'0';
    while(isdigit(IN=getchar()))
        x = x*10+IN-'0';
    if(NEG)x = -x;
}
inline void LL(ll &x){
    NEG = 0;
    while(!isdigit(IN=getchar()))
        if(IN=='-')NEG = 1;
    x = IN-'0';
    while(isdigit(IN=getchar()))
        x = x*10+IN-'0';
    if(NEG)x = -x;
}
inline void out(ll x){
    top = 0;
    while(x){
        OUT[++top] = x%10;
        x /= 10;
    }
    if(!top)putchar('0');
    while(top)putchar(char('0'+OUT[top--]));
    puts("");
}

/******** program ********************/

const int MAXN = 200005;
const ll INF = 1e15;

ll ans[MAXN],sum[MAXN];
int val[MAXN],n,m;

struct node{
    int x,y,val;
    node(){}
    node(int _x,int _y,int _val):x(_x),y(_y),val(_val){}
    friend bool operator < (node a,node b){
        return a.x>b.x;
    }
}p[MAXN],a[MAXN],b[MAXN];

struct segTree{
    int l,r;
    ll mx;
    inline int mid(){
        return (l+r)>>1;
    }
}tree[MAXN<<2];

void build(int l,int r,int rt){
    tree[rt].l = l;
    tree[rt].r = r;
    tree[rt].mx = INF;
    if(l==r)return;
    int mid = tree[rt].mid();
    build(l,mid,lson);
    build(mid+1,r,rson);
}

void modify(int pos,ll val,int rt){
    if(tree[rt].l==tree[rt].r){
        cmin(tree[rt].mx,val);
        return;
    }
    int mid = tree[rt].mid();
    if(pos<=mid)modify(pos,val,lson);
    else modify(pos,val,rson);
    tree[rt].mx = min(tree[lson].mx,tree[rson].mx);
}

ll ask(int l,int r,int rt){
    if(l<=tree[rt].l&&tree[rt].r<=r)
        return tree[rt].mx;
    int mid = tree[rt].mid();
    if(r<=mid)return ask(l,r,lson);
    else if(l>mid)return ask(l,r,rson);
    else return min(ask(l,r,lson),ask(l,r,rson));
}

int main(){

#ifndef ONLINE_JUDGE
    freopen("sum.in","r",stdin);
    //freopen("sum.out","w",stdout);
#endif

    while(~RD2(n,m)){
        REP(i,2,n){
            Int(val[i]);
            sum[i] = sum[i-1]+val[i];
        }
        rep1(i,m){
            Int(p[i].x);
            Int(p[i].y);
            Int(p[i].val);
        }

        int qq;
        Int(qq);
        int na = 0 , nb = 0 , x , y;
        rep1(i,qq){
            Int(x);
            Int(y);
            if(x>y)b[++nb] = node(x,y,i);
            else a[++na] = node(x,y,i);
        }

        sort(a+1,a+na+1);
        sort(p+1,p+m+1);
        int pos = 1;

        build(1,n,1);
        rep1(i,na){
            while(pos<=m&&p[pos].x>=a[i].x){
                x = p[pos].x , y = p[pos].y;
                if(x<=y)
                    modify(y,p[pos].val-(sum[y]-sum[x]),1 );
                pos ++;
            }

            ll tmp = ask(a[i].x,a[i].y,1);
            if(tmp>0)tmp = 0;
            ans[ a[i].val ] = sum[ a[i].y ]-sum[ a[i].x ]+tmp;
        }

        sort(b+1,b+nb+1);
        pos = 1;

        build(1,n,1);
        rep1(i,nb){
            while( pos<=m&&p[pos].x>=b[i].x ){
                x = p[pos].x , y = p[pos].y;
                if(x>=y)
                    modify(y,sum[x]-sum[y]+p[pos].val,1);
                pos ++;
            }
            ans[ b[i].val ] = ask(1,b[i].y,1)-(sum[b[i].x]-sum[b[i].y]);
        }

        rep1(i,qq)
            out(ans[i]);
    }

    return 0;
}

  

 

 

 

posted @ 2013-09-18 19:23  yejinru  阅读(299)  评论(0编辑  收藏  举报