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
维护每条路的最早使用天数和最后使用天数
这个可以用线段树来区间维护最大最小值
排序后按照使用时间扫一遍就好了
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct tree
{
int l,r;
int ma,mi;
int tag1,tag2;
}tr[1600001];
inline void up(int p)
{
if(tr[p].l==tr[p].r)
return ;
tr[p].ma=max(tr[p*2].ma,tr[p*2+1].ma);
tr[p].mi=min(tr[p*2].mi,tr[p*2+1].mi);
}
inline void push(int p)
{
if(tr[p].l==tr[p].r)
return ;
tr[p*2].ma=max(tr[p].tag1,tr[p*2].ma);
tr[p*2+1].ma=max(tr[p].tag1,tr[p*2+1].ma);
tr[p*2].tag1=max(tr[p].tag1,tr[p*2].tag1);
tr[p*2+1].tag1=max(tr[p].tag1,tr[p*2+1].tag1);
tr[p].tag1=0;
tr[p*2].mi=min(tr[p].tag2,tr[p*2].mi);
tr[p*2+1].mi=min(tr[p].tag2,tr[p*2+1].mi);
tr[p*2].tag2=min(tr[p].tag2,tr[p*2].tag2);
tr[p*2+1].tag2=min(tr[p].tag2,tr[p*2+1].tag2);
tr[p].tag2=2100000000;
}
inline void build(int p,int l,int r)
{
tr[p].l=l;
tr[p].r=r;
if(l!=r)
{
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
up(p);
tr[p].tag1=0;
tr[p].tag2=2100000000;
}
else
{
tr[p].ma=0;
tr[p].mi=2100000000;
tr[p].tag1=0;
tr[p].tag2=2100000000;
}
}
inline void change1(int p,int l,int r,int x)
{
if(l<=tr[p].l&&tr[p].r<=r)
{
tr[p].ma=max(tr[p].ma,x);
tr[p].tag1=max(tr[p].tag1,x);
}
else
{
push(p);
int mid=(tr[p].l+tr[p].r)/2;
if(l<=mid)
change1(p*2,l,r,x);
if(r>mid)
change1(p*2+1,l,r,x);
up(p);
}
}
inline void change2(int p,int l,int r,int x)
{
if(l<=tr[p].l&&tr[p].r<=r)
{
tr[p].mi=min(tr[p].mi,x);
tr[p].tag2=min(tr[p].tag2,x);
}
else
{
push(p);
int mid=(tr[p].l+tr[p].r)/2;
if(l<=mid)
change2(p*2,l,r,x);
if(r>mid)
change2(p*2+1,l,r,x);
up(p);
}
}
inline int ask1(int p,int l,int r)
{
if(l<=tr[p].l&&tr[p].r<=r)
return tr[p].ma;
else
{
push(p);
int mid=(tr[p].l+tr[p].r)/2;
int ans=0;
if(l<=mid)
ans=max(ans,ask1(p*2,l,r));
if(r>mid)
ans=max(ans,ask1(p*2+1,l,r));
up(p);
return ans;
}
}
inline int ask2(int p,int l,int r)
{
if(l<=tr[p].l&&tr[p].r<=r)
return tr[p].mi;
else
{
push(p);
int mid=(tr[p].l+tr[p].r)/2;
int ans=2100000000;
if(l<=mid)
ans=min(ans,ask2(p*2,l,r));
if(r>mid)
ans=min(ans,ask2(p*2+1,l,r));
up(p);
return ans;
}
}
int a[200001];
struct ques
{
int l,r;
int x,s,p;
}b[200001],c[200001];
inline bool cmp1(ques x,ques y)
{
return x.l<y.l;
}
inline bool cmp2(ques x,ques y)
{
return x.r<y.r;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
int i,j;
for(i=1;i<=n-1;i++)
scanf("%d",&a[i]);
build(1,1,n-1);
int s,t;
for(j=1;j<=m;j++)
{
scanf("%d%d",&s,&t);
if(s>(t-1))
{
int tt=s;
s=t;
t=tt;
}
change1(1,s,t-1,j);
change2(1,s,t-1,j);
}
for(i=1;i<=n-1;i++)
{
b[i].l=ask2(1,i,i);
b[i].r=ask1(1,i,i);
b[i].p=i;
c[i].l=b[i].l;
c[i].r=b[i].r;
c[i].p=i;
}
sort(b+1,b+n,cmp1);
sort(c+1,c+n,cmp2);
int j1=1,j2=1;
int ans=0;
for(i=1;i<=m;i++)
{
while(j1<=n-1&&b[j1].l<=i)
{
if(b[j1].l<=b[j1].r)
ans+=a[b[j1].p];
j1++;
}
while(j2<=n-1&&c[j2].r<i)
{
if(c[j2].l<=c[j2].r)
ans-=a[c[j2].p];
j2++;
}
printf("%d\n",ans);
}
}
return 0;
}