Hdu 5861 Road

考虑到每一个线段只有一次进入答案的机会和离开答案的机会

用线段树求得每个线段进入答案和离开答案的时间

暴力计算即可

时间复杂度 O(m×log(n)+max(n,m))

#include<bits/stdc++.h>
using namespace std;

const int maxn = 212345;

int arr[maxn * 4];

#define root 1,1,n
#define lson o<<1,l,m
#define rson o<<1|1,m+1,r
#define Now int o,int l,int r
#define Mid int m = (l + r) >> 1;

void update(Now,int ul,int ur,int v){
    if(ul <= l && r <= ur){
        arr[o] = v;
        return;
    }
    Mid;
    if(arr[o] != -1){
        arr[o<<1] = arr[o<<1|1] = arr[o];
        arr[o] = -1;
    }
    if(ul <= m) update(lson,ul,ur,v);
    if(m+1<=ur) update(rson,ul,ur,v);
}

int query(Now,int pos){
    if(l == r){
        return arr[o];
    }
    if(arr[o] != -1) return arr[o];
    Mid;
    if(pos <= m) return query(lson,pos);
    else return query(rson,pos);
}

vector<int> in[maxn],out[maxn];
int L[maxn],R[maxn];
int v[maxn];

int main(){
    int n,m;
    while(~scanf("%d %d",&n,&m)){
        for(int i=0;i<=m+1;i++){
            in[i].clear();
            out[i].clear();
        }
        for(int i=1;i<n;i++) scanf("%d",&v[i]);
        for(int i=1;i<=m;i++){
            scanf("%d %d",&L[i],&R[i]);
            if(L[i] > R[i])
                swap(L[i],R[i]);
        }

        memset(arr,-1,sizeof(arr));
        for(int i=m;i>=1;i--){
            update(root,L[i],R[i]-1,i);
        }
        for(int i=1;i<n;i++){
            int tim = query(root,i);
            if(tim != -1){
                in[tim].push_back(i);
            }
        }

        memset(arr,-1,sizeof(arr));
        for(int i=1;i<=m;i++){
            update(root,L[i],R[i]-1,i);
        }
        for(int i=1;i<n;i++){
            int tim = query(root,i);
            if(tim != -1){
                out[tim].push_back(i);
            }
        }
        int ans = 0;
        for(int i=1;i<=m;i++){
            for(auto x : in[i])
                ans += v[x];
            printf("%d\n",ans);
            for(auto x : out[i])
                ans -= v[x];
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值