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.)
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
这里我是用线段树维护每条路最一开始需要用到的时间,和最后用到的时间。把最早的时间和最晚的时间加入到优先队列中。如果有就加入答案,没有就提出答案即可。
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|1
const 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]);
}
}