hdu5861 Road(线段树成段更新+优先队)

来源:互联网 发布:上古世纪捏脸数据在那 编辑:程序博客网 时间:2024/05/22 01:40

Road

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


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(1ai,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 31 2 31 33 42 4
 

Sample Output
355
 
题意是给你n个村庄,每两个相邻的村庄有一条路,m个操作,每次都要从一个村庄走到另外一个村庄,每一条路每次都有一个维修的费用,每条路一开始是关闭的,你可以打开一次,关闭一次。问你最少的费用是多少。

这里我是用线段树维护每条路最一开始需要用到的时间,和最后用到的时间。把最早的时间和最晚的时间加入到优先队列中。如果有就加入答案,没有就提出答案即可。

AC代码:

#include<stdio.h>#include<algorithm>#include<iostream>#include<queue>#define ll __int64#include<string.h>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1const int maxn=220000;const int inf=1<<27;int maxx[maxn<<2],minn[maxn<<2];int col[maxn<<2];int a[maxn];int ans[maxn];struct node{    int v,id;    bool operator <(node z)const    {        return id>z.id;    }};priority_queue<node>Q1; priority_queue<node>Q2; node a1;void Pushup(int rt){    maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]);    minn[rt]=min(minn[rt<<1],minn[rt<<1|1]);    return;}void Pushdown(int rt){//延迟更新    if(col[rt]){        col[rt<<1]=col[rt<<1|1]=col[rt];        maxx[rt<<1]=max(maxx[rt<<1],maxx[rt]);        maxx[rt<<1|1]=max(maxx[rt<<1|1],maxx[rt]);        minn[rt<<1]=min(minn[rt<<1],minn[rt]);        minn[rt<<1|1]=min(minn[rt<<1|1],minn[rt]);        col[rt]=0;    }}void build(int l,int r,int rt){    int m=l+r>>1;    maxx[rt]=0;    col[rt]=0;    minn[rt]=inf;    if(l==r){               return;    }        build(lson);    build(rson);    Pushup(rt);}void Update(int L,int R,int x,int l,int r,int rt){//更新最大最小值    int m=l+r>>1;    if(L<=l && r<=R){        maxx[rt]=max(maxx[rt],x);        minn[rt]=min(minn[rt],x);        col[rt]=1;        return;    }    Pushdown(rt);    if(L<=m)    Update(L,R,x,lson);    if(m<R)        Update(L,R,x,rson);}void serch(int l,int r,int rt){//找到最大最小值    int m=l+r>>1;    if(l==r){        if(maxx[rt]!=0)        {          a1.v=a[l];          a1.id=minn[rt];          Q1.push(a1);          a1.id=maxx[rt];          Q2.push(a1);         }                        return;    }    Pushdown(rt);    serch(lson);    serch(rson);}int main(){    int n,m;    while(scanf("%d%d",&n,&m)==2){        memset(col,0,sizeof(col));        memset(maxx,0,sizeof(maxx));        memset(minn,0,sizeof(minn));        for(int i=1;i<n;i++){            scanf("%d",&a[i]);        }        build(1,n-1,1);        for(int i=1;i<=m;i++){            int l,r;            scanf("%d%d",&l,&r);            int a,b;            a=min(l,r);            b=max(l,r);            Update(a,b-1,i,1,n-1,1);        }        serch(1,n-1,1);        int tot=0;        for(int i=1;i<=m;i++)        {                        while(!Q1.empty())             {                 node t=Q1.top();                 Q1.pop();                 if(t.id==i)tot+=t.v;                 else                 {                     Q1.push(t);                     break;                }             }             ans[i]=tot;             while(!Q2.empty())             {                 node t=Q2.top();                 Q2.pop();                 if(t.id==i)tot-=t.v;                 else                  {                     Q2.push(t);                     break;                }             }        }        for(int i=1;i<=m;i++)        printf("%d\n",ans[i]);    }    }




0 0
原创粉丝点击