HDU 5861 Road 线段树

//HDU 5861 
#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
using namespace std;

#define inf 0x3f3f3f3f
const int maxn = 2e5+5;

int minn[maxn<<2], maxx[maxn<<2];  //开启时间的左右区间 
int val[maxn];

void build(int i, int l, int r)
{
    minn[i] = inf, maxx[i] = -1;
    if(l ==  r) return;
    int mid = (l+r)/2;
    build(i*2, l, mid);
    build(i*2+1, mid+1, r);
}

void pushdown(int i)
{
    if(minn[i] != inf)
    {
        minn[2*i] = min(minn[2*i], minn[i]);
        minn[2*i+1] = min(minn[2*i+1], minn[i]);
    }
    if(maxx[i] != -1)
    {
        maxx[2*i] = max(maxx[2*i], maxx[i]);
        maxx[2*i+1] = max(maxx[2*i+1], maxx[i]);
    }
}

void update(int i, int l, int r, int ll, int rr, int t)
{
    if(l >= ll && r <= rr)
    {
        minn[i] = min(minn[i], t);
        maxx[i] = max(maxx[i], t);
        return;
    }
    pushdown(i);
    int mid = (l+r)/2;
    if(mid >= ll) update(2*i, l, mid, ll, rr, t);
    if(mid+1 <= rr) update(2*i+1, mid+1, r, ll, rr, t);
}

//获得每个时间的需要开启的路段和每个时间可以关闭的路段 
vector<int> s[maxn], e[maxn];
void fun(int i, int l, int r)
{
    if(l == r)
    {
        if(minn[i] != inf) s[minn[i]].push_back(l);
        if(maxx[i] != -1) e[maxx[i]].push_back(l);
        return;
    }
    pushdown(i);
    int mid = (l+r)/2;
    fun(2*i, l, mid);
    fun(2*i+1, mid+1, r);
}

int main()
{
    int n, m;
    while(~scanf("%d %d", &n, &m))
    {
        for(int i = 0; i < maxn; i++) s[i].clear();
        for(int i = 0; i < maxn; i++) e[i].clear();
        build(1, 1, n-1);
        for(int i = 1; i <= n-1; i++) scanf("%d", &val[i]);
        for(int i = 1; i <= m; i++)
        {
            int a, b;
            scanf("%d %d", &a, &b);
            if(a > b) swap(a, b);
            update(1, 1, n-1, a, b-1, i);
        }

        fun(1, 1, n-1);
        int ans = 0;
        for(int i = 1; i <= m; i++)
        {
            for(int j = 0; j < s[i].size(); j++) //i时开启的路段 
                ans += val[s[i][j]];
                
            printf("%d\n", ans);
            
            for(int j = 0; j < e[i].size(); j++) //i时后关闭的路段 
                ans -= val[e[i][j]];
        }
    }
    //system("pause");
    return 0;
}
上一篇:前端开发环境准备


下一篇:[NOIp2013] 货车运输 题解