• 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
    " :: "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;
    }
    

      

  • 相关阅读:
    Bytom资产发行与部署合约教程
    币币合约执行解析(包含部分源码)
    Bytom猜谜合约使用指南
    Bytom移动端钱包SDK开发基础
    Bytom矿池接入协议指南
    Bytom交易说明(UTXO用户自己管理模式)
    Derek解读Bytom源码-创世区块
    Derek解读Bytom源码-持久化存储LevelDB
    编写生成彩色验证码的Servlet
    最长公共子序列问题
  • 原文地址:https://www.cnblogs.com/yejinru/p/3329023.html
Copyright © 2020-2023  润新知