HDU 5861 Road(线段树 区间修改 单点查询)

Road

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1132    Accepted Submission(s): 309

Problem Description

There are n villages along a high way, and divided the high way into n-1 segments. Each segment would charge a certain amount of money for being open for one day, and you can open or close an arbitrary segment in an arbitrary day, but you can open or close the segment for just one time, because the workers would be angry if you told them to work multiple period.
We know the transport plan in the next m days, each day there is one cargo need to transport from village ai to village bi, and you need to guarantee that the segments between ai and bi are open in the i-th day. Your boss wants to minimize the total cost of the next m days, and you need to tell him the charge for each day.
(At the beginning, all the segments are closed.)

Input

Multiple test case. For each test case, begins with two integers n, m(1<=n,m<=200000), next line contains n-1 integers. The i-th integer wi(1<=wi<=1000) indicates the charge for the segment between village i and village i+1 being open for one day. Next m lines, each line contains two integers ai,bi(1≤ai,bi<=n,ai!=bi).

Output

For each test case, output m lines, each line contains the charge for the i-th day.

Sample Input

4 3
1 2 3
1 3
3 4
2 4

Sample Output

3
5
5

Author

BUPT

Source

2016 Multi-University Training Contest 10

【题意】n个点将一条线段分成n-1份,点的编号从左往右1~n,每条路你只能打开一次,打开后每天都收费,当然打开后你也可以选择关上,但是关上后这条路就再也不能打开了。每条线段有一个Cost值,然后Q次询问,没次询问给出两个点U,V,表示从U,到V,你必须保证U->V上的线段都打开才能过去,然后问你在保证你能过去的情况下,每天的最小花费。

【分析】要想避免无用的花费,那么我们可以对于每条路,他第一次使用就把它打开,他最后一条使用完过后就把它关了,因为这条路再也不用了。那么我们可以先找到每条路的打开时间和关闭时间,这个类似于区间覆盖,所以我们可以用线段树来维护,复杂度NlogN。然后就是要找到当前天,有多少路是打开的,这个我们可以用一个类似于莫队的做法,假设对于前一天我们已经知道了答案,那么对于今天,我们只要知道有多少条路是今天打开的和关闭的,那么我们今天就可以根据前一天的来推,复杂度O(M);

#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define met(a,b) memset(a,b,sizeof a)
#define inf 10000000
using namespace std;
typedef long long ll;
typedef pair<int,int>pii;
const int N = 4e5+5;
const double eps = 1e-8;
int n,sum[2*N],m;
int lazy[2*N],a[N],mi[N*2],ma[N*2];
vector<int>st[N],en[N];
struct man{
    int u,v;
}q[N];
void init(){
    for(int i=0;i<N;i++){
        st[i].clear();
        en[i].clear();
    }
}
void pushDown(int pos){
     if(mi[pos]!=inf){
        mi[pos*2]=min(mi[pos*2],mi[pos]);
        mi[pos*2+1]=min(mi[pos*2+1],mi[pos]);
    }
    if(ma[pos]!=0){
        ma[pos*2]=max(ma[pos*2],ma[pos]);
        ma[pos*2+1]=max(ma[pos*2+1],ma[pos]);
    }
    return;
}

void update(int L,int R,int val,int l,int r,int pos) {
    if(l>=L&&r<=R) {
        mi[pos]=min(mi[pos],val);
        ma[pos]=max(ma[pos],val);
        return;
    }
    int mid=(l+r)>>1;
    pushDown(pos);
    if(L<=mid) update(L,R,val,l,mid,pos<<1);
    if(mid<R)update(L,R,val,mid+1,r,pos<<1|1);
}
void  query(int l,int r,int pos) {
    if(l==r){
        if(mi[pos]!=inf)st[mi[pos]].pb(l);
        if(ma[pos]!=0)en[ma[pos]+1].pb(l);
        return;
    }
    int mid=(l+r)>>1;
    pushDown(pos);
    query(l,mid,pos<<1);
    query(mid+1,r,pos<<1|1);
    return;
}
void build(int l,int r,int pos){
    mi[pos]=inf;
    ma[pos]=0;
    if(l==r){
        return;
    }
    int mid=(l+r)/2;
    build(l,mid,pos*2);
    build(mid+1,r,pos*2+1);
}
int main() {
    int ll,rr,cnt=0;
    while(~scanf("%d%d",&n,&m)){
        init();
        build(1,n-1,1);
        for(int i=1;i<n;i++){
            scanf("%d",&a[i]);
        }
        for(int i=1;i<=m;i++){
            scanf("%d%d",&q[i].u,&q[i].v);
            if(q[i].u>q[i].v)swap(q[i].u,q[i].v);
            update(q[i].u,q[i].v-1,i,1,n-1,1);
        }
        query(1,n-1,1);
        int ans=0;
        for(int i=1;i<=m;i++){
            for(int x:st[i]){
                ans+=a[x];
            }
            for(int x:en[i]){
                ans-=a[x];
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}
时间: 2024-08-27 13:05:55

HDU 5861 Road(线段树 区间修改 单点查询)的相关文章

Wikilo 1191线段树区间修改单点查询

这题也算比较容易的了. 如果哪个区间已经没有黑色的话,就不用update了,就是因为这个原因WA了2发,唉-- #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string> #incl

线段树区间修改与查询

单点修改与查询 //单点修改,区间询问最小值 #include <iostream> #include <cstdio> #define maxn 101 #define INF 0x7fffffff using namespace std; int a[maxn],n,m; int mi[maxn]; void build(int k,int l,int r)//k是当前节点编号,l,r为当前节点代表区间 { if(l==r) { mi[k]=a[l]; return; } in

Light OJ 1080 - Binary Simulation - (线段树区间更新 单点查询)

Description Given a binary number, we are about to do some operations on the number. Two types of operations can be here. 'I i j'    which means invert the bit from i to j (inclusive) 'Q i'    answer whether the ith bit is 0 or 1 The MSB (most signif

ZOJ 1610 Count the Colors【题意+线段树区间更新&amp;&amp;单点查询】

任意门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1610 Count the Colors Time Limit: 2 Seconds      Memory Limit: 65536 KB Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent

POJ 3468 A Simple Problem with Integers(线段树区间修改及查询)

Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval. In

uva 1401 Fast Matrix Operations 快速矩阵操作 (线段树 区间修改和查询)

题意:给一个r行c列的全0矩阵,支持以下三种操作: 1 x1 y1 x2 y2 v 子矩阵(x1 y1 x2 y2)的所有元素增加v 2 x1 y1 x2 y2 v 子矩阵(x1 y1 x2 y2)的所有元素设为v 3 x1 y1 x2 y2   查询子矩阵(x1 y1 x2 y2)的元素和.最小值.最大值. 子矩阵(x1 y1 x2 y2)是指满足 x1 <= x <= x2, y1 <= y <= y2的所有元素(x,y). 矩阵不超过20行,矩阵总元素可多达10^6个. 思路

ZOJ 1610 Count the Colors(线段树,区间覆盖,单点查询)

Count the Colors Time Limit: 2 Seconds      Memory Limit: 65536 KB Painting some colored segments on a line, some previously painted segments may be covered by some the subsequent ones. Your task is counting the segments of different colors you can s

hdu1698 Just a Hook(线段树+区间修改+区间查询+模板)

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 54923    Accepted Submission(s): 25566 Problem Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of

HDU - 1698 Just a Hook (线段树区间修改)

Description In the game of DotA, Pudge's meat hook is actually the most horrible thing for most of the heroes. The hook is made up of several consecutive metallic sticks which are of the same length. Now Pudge wants to do some operations on the hook.